From e099224bc5948dd604632f1602017b99cb29cc90 Mon Sep 17 00:00:00 2001 From: mittorn Date: Wed, 29 Mar 2017 19:59:50 +0000 Subject: [PATCH 001/211] Use vgui2 functions for utf-8 print --- cl_dll/MOTD.cpp | 2 +- cl_dll/cl_util.h | 2 ++ cl_dll/hud_redraw.cpp | 29 +++++++++++++++++++++++++++++ cl_dll/scoreboard.cpp | 24 ++++++++++++------------ 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/cl_dll/MOTD.cpp b/cl_dll/MOTD.cpp index 6ab3a161..179ae4a8 100644 --- a/cl_dll/MOTD.cpp +++ b/cl_dll/MOTD.cpp @@ -103,7 +103,7 @@ int CHudMOTD::Draw( float fTime ) // find where to start drawing the line if( ( ypos > ROW_RANGE_MIN ) && ( ypos + LINE_HEIGHT <= ypos_r + height ) ) - gHUD.DrawHudString( xpos, ypos, xmax, ch, 255, 180, 0 ); + DrawUtfString( xpos, ypos, xmax, ch, 255, 180, 0 ); ypos += LINE_HEIGHT; diff --git a/cl_dll/cl_util.h b/cl_dll/cl_util.h index 84488050..54dcede0 100644 --- a/cl_dll/cl_util.h +++ b/cl_dll/cl_util.h @@ -115,6 +115,8 @@ inline void GetConsoleStringSize( const char *string, int *width, int *height ) gEngfuncs.pfnDrawConsoleStringLen( (char*)string, width, height ); } +int DrawUtfString( int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b ); + inline int ConsoleStringLen( const char *string ) { int _width = 0, _height = 0; diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index aed98455..b5314961 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -226,6 +226,35 @@ int CHud::DrawHudString( int xpos, int ypos, int iMaxX, char *szIt, int r, int g return xpos; } + + +int DrawUtfString( int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b ) +{ + // xash3d: reset unicode state + gEngfuncs.pfnVGUI2DrawCharacterAdditive( 0, 0, 0, 0, 0, 0, 0 ); + + // draw the string until we hit the null character or a newline character + for( ; *szIt != 0 && *szIt != '\n'; szIt++ ) + { + int w = gHUD.m_scrinfo.charWidths['M']; + if( xpos + w > iMaxX ) + return xpos; + if( ( *szIt == '^' ) && ( *( szIt + 1 ) >= '0') && ( *( szIt + 1 ) <= '7') ) + { + szIt++; + r = colors[*szIt - '0'][0]; + g = colors[*szIt - '0'][1]; + b = colors[*szIt - '0'][2]; + if( !*(++szIt) ) + return xpos; + } + int c = (unsigned int)(unsigned char)*szIt; + xpos += gEngfuncs.pfnVGUI2DrawCharacterAdditive( xpos, ypos, c, r, g, b, 0 ); + } + + return xpos; +} + int CHud::DrawHudStringLen( char *szIt ) { int l = 0; diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index 2e0722f9..3a780baf 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -146,18 +146,18 @@ int CHudScoreboard::Draw( float fTime ) FAR_RIGHT += 5; gHUD.DrawDarkRectangle( xpos - 5, ypos - 5, FAR_RIGHT, ROW_RANGE_MAX ); if( !gHUD.m_Teamplay ) - gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Player", 255, 140, 0 ); + DrawUtfString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Player", 255, 140, 0 ); else - gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Teams", 255, 140, 0 ); + DrawUtfString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Teams", 255, 140, 0 ); gHUD.DrawHudStringReverse( KILLS_RANGE_MAX + xpos_rel, ypos, 0, "kills", 255, 140, 0 ); - gHUD.DrawHudString( DIVIDER_POS + xpos_rel, ypos, ScreenWidth, "/", 255, 140, 0 ); - gHUD.DrawHudString( DEATHS_RANGE_MIN + xpos_rel + 5, ypos, ScreenWidth, "deaths", 255, 140, 0 ); - gHUD.DrawHudString( PING_RANGE_MAX + xpos_rel - 35, ypos, ScreenWidth, "latency", 255, 140, 0 ); + DrawUtfString( DIVIDER_POS + xpos_rel, ypos, ScreenWidth, "/", 255, 140, 0 ); + DrawUtfString( DEATHS_RANGE_MIN + xpos_rel + 5, ypos, ScreenWidth, "deaths", 255, 140, 0 ); + DrawUtfString( PING_RANGE_MAX + xpos_rel - 35, ypos, ScreenWidth, "latency", 255, 140, 0 ); if( can_show_packetloss ) { - gHUD.DrawHudString( PL_RANGE_MAX + xpos_rel - 35, ypos, ScreenWidth, "pkt loss", 255, 140, 0 ); + DrawUtfString( PL_RANGE_MAX + xpos_rel - 35, ypos, ScreenWidth, "pkt loss", 255, 140, 0 ); } list_slot += 1.2; @@ -272,7 +272,7 @@ int CHudScoreboard::Draw( float fTime ) } // draw their name (left to right) - gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, team_info->name, r, g, b ); + DrawUtfString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, team_info->name, r, g, b ); // draw kills (right to left) xpos = KILLS_RANGE_MAX + xpos_rel; @@ -280,7 +280,7 @@ int CHudScoreboard::Draw( float fTime ) // draw divider xpos = DIVIDER_POS + xpos_rel; - gHUD.DrawHudString( xpos, ypos, xpos + 20, "/", r, g, b ); + DrawUtfString( xpos, ypos, xpos + 20, "/", r, g, b ); // draw deaths xpos = DEATHS_RANGE_MAX + xpos_rel; @@ -300,7 +300,7 @@ int CHudScoreboard::Draw( float fTime ) xpos = ( ( PL_RANGE_MAX - PL_RANGE_MIN ) / 2) + PL_RANGE_MIN + xpos_rel + 25; sprintf( buf, " %d", team_info->packetloss ); - gHUD.DrawHudString( xpos, ypos, xpos+50, buf, r, g, b ); + DrawUtfString( xpos, ypos, xpos+50, buf, r, g, b ); } team_info->already_drawn = TRUE; // set the already_drawn to be TRUE, so this team won't get drawn again @@ -400,7 +400,7 @@ int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, } // draw their name (left to right) - gHUD.DrawHudString( xpos + nameoffset, ypos, NAME_RANGE_MAX + xpos_rel, pl_info->name, r, g, b ); + DrawUtfString( xpos + nameoffset, ypos, NAME_RANGE_MAX + xpos_rel, pl_info->name, r, g, b ); // draw kills (right to left) xpos = KILLS_RANGE_MAX + xpos_rel; @@ -408,7 +408,7 @@ int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, // draw divider xpos = DIVIDER_POS + xpos_rel; - gHUD.DrawHudString( xpos, ypos, xpos + 20, "/", r, g, b ); + DrawUtfString( xpos, ypos, xpos + 20, "/", r, g, b ); // draw deaths xpos = DEATHS_RANGE_MAX + xpos_rel; @@ -435,7 +435,7 @@ int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, xpos = ( ( PL_RANGE_MAX - PL_RANGE_MIN ) / 2 ) + PL_RANGE_MIN + xpos_rel + 25; - gHUD.DrawHudString( xpos, ypos, xpos+50, buf, r, g, b ); + DrawUtfString( xpos, ypos, xpos+50, buf, r, g, b ); } pl_info->name = NULL; // set the name to be NULL, so this client won't get drawn again From 409848b80fd02893f6eb34cd97e18cd93c2ada04 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 3 Apr 2017 21:16:25 +0500 Subject: [PATCH 002/211] Do not break menuselect behavior. --- dlls/client.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/client.cpp b/dlls/client.cpp index 21e5d810..5fb7c221 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -466,10 +466,10 @@ void ClientCommand( edict_t *pEntity ) edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer ); pPlayer->StartObserver( pev->origin, VARS( pentSpawnSpot )->angles ); } - /*else if( g_pGameRules->ClientCommand( GetClassPtr( (CBasePlayer *)pev ), pcmd ) ) + else if( g_pGameRules->ClientCommand( GetClassPtr( (CBasePlayer *)pev ), pcmd ) ) { // MenuSelect returns true only if the command is properly handled, so don't print a warning - }*/ + } else if( FStrEq( pcmd, "VModEnable" ) ) { // clear 'Unknown command: VModEnable' in singleplayer From 4fbb070e7d59c8dc660f5895ba8470fe869cd49a Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 4 Apr 2017 01:15:16 +0500 Subject: [PATCH 003/211] Implement cl_scoreboard_bg cvar. --- cl_dll/scoreboard.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index 3a780baf..507e0415 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -26,6 +26,7 @@ #include #include +cvar_t *cl_scoreboard_bg; cvar_t *cl_showpacketloss; hud_player_info_t g_PlayerInfoList[MAX_PLAYERS + 1]; // player info from the engine extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS + 1]; // additional player info sent directly to the client dll @@ -59,6 +60,7 @@ int CHudScoreboard::Init( void ) InitHUDData(); + cl_scoreboard_bg = CVAR_CREATE( "cl_scoreboard_bg", "1", 0 ); cl_showpacketloss = CVAR_CREATE( "cl_showpacketloss", "0", FCVAR_ARCHIVE ); return 1; @@ -144,7 +146,8 @@ int CHudScoreboard::Draw( float fTime ) FAR_RIGHT = can_show_packetloss ? PL_RANGE_MAX : PING_RANGE_MAX; FAR_RIGHT += 5; - gHUD.DrawDarkRectangle( xpos - 5, ypos - 5, FAR_RIGHT, ROW_RANGE_MAX ); + if( cl_scoreboard_bg && cl_scoreboard_bg->value ) + gHUD.DrawDarkRectangle( xpos - 5, ypos - 5, FAR_RIGHT, ROW_RANGE_MAX ); if( !gHUD.m_Teamplay ) DrawUtfString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Player", 255, 140, 0 ); else From 6f8d64df898ba58f1d5c3cd6f81951f38d6f74dd Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 4 Apr 2017 01:43:21 +0500 Subject: [PATCH 004/211] Make cl_scoreboard_bg cvar archive. --- cl_dll/scoreboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index 507e0415..b20e316c 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -60,7 +60,7 @@ int CHudScoreboard::Init( void ) InitHUDData(); - cl_scoreboard_bg = CVAR_CREATE( "cl_scoreboard_bg", "1", 0 ); + cl_scoreboard_bg = CVAR_CREATE( "cl_scoreboard_bg", "1", FCVAR_ARCHIVE ); cl_showpacketloss = CVAR_CREATE( "cl_showpacketloss", "0", FCVAR_ARCHIVE ); return 1; From 8163bced2c29e22629b3c3c3541d131fed00bfdf Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 12 Apr 2017 02:02:18 +0500 Subject: [PATCH 005/211] Do not break hud_takesshots cvar behavior. --- cl_dll/hud_redraw.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index b5314961..c30df36d 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -93,6 +93,13 @@ int CHud::Redraw( float flTime, int intermission ) if( m_flTimeDelta < 0 ) m_flTimeDelta = 0; + if( !m_iIntermission && intermission ) + { + // Take a screenshot if the client's got the cvar set + if( CVAR_GET_FLOAT( "hud_takesshots" ) != 0 ) + m_flShotTime = flTime + 1.0; // Take a screenshot in a second + } + if( m_flShotTime && m_flShotTime < flTime ) { gEngfuncs.pfnClientCmd( "snapshot\n" ); From fc276ad52f51ec128352ac680ef9cbac038e6b23 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Fri, 16 Jun 2017 19:18:24 +0500 Subject: [PATCH 006/211] Do not use -frtti flag. --- dlls/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/Android.mk b/dlls/Android.mk index 7f107a12..7fcdf581 100644 --- a/dlls/Android.mk +++ b/dlls/Android.mk @@ -16,7 +16,7 @@ endif LOCAL_CFLAGS += -D_LINUX -DCLIENT_WEAPONS -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf \ -fno-exceptions -DNO_VOICEGAMEMGR -w -LOCAL_CPPFLAGS := $(LOCAL_CFLAGS) -frtti +LOCAL_CPPFLAGS := $(LOCAL_CFLAGS) LOCAL_C_INCLUDES := $(SDL_PATH)/include \ $(LOCAL_PATH)/. \ From a522ae20c3dcb7b48381205254021796db914d14 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 26 Jun 2017 05:47:19 +0500 Subject: [PATCH 007/211] Merge some changes from git version of hlsdk. --- common/const.h | 11 +- common/cvardef.h | 3 +- dlls/buttons.cpp | 6 +- dlls/cbase.h | 4 +- dlls/client.cpp | 238 ++++++++++++++++++++++++++++------- dlls/crossbow.cpp | 4 +- dlls/crowbar.cpp | 9 +- dlls/doors.cpp | 9 +- dlls/extdll.h | 2 +- dlls/game.cpp | 2 + dlls/gauss.cpp | 4 +- dlls/handgrenade.cpp | 4 +- dlls/mp5.cpp | 4 +- dlls/multiplay_gamerules.cpp | 4 +- dlls/nihilanth.cpp | 18 ++- dlls/player.cpp | 115 +++++++++++++++-- dlls/player.h | 12 ++ dlls/rpg.cpp | 4 +- dlls/satchel.cpp | 6 +- dlls/saverestore.h | 2 +- dlls/shotgun.cpp | 10 +- dlls/squeakgrenade.cpp | 2 +- dlls/subs.cpp | 8 ++ dlls/triggers.cpp | 2 +- dlls/tripmine.cpp | 2 +- dlls/util.cpp | 4 +- dlls/util.h | 2 +- dlls/weapons.cpp | 36 ++++++ dlls/weapons.h | 5 + dlls/zombie.cpp | 6 +- engine/eiface.h | 17 +-- engine/shake.h | 4 +- engine/studio.h | 10 +- pm_shared/pm_defs.h | 2 +- pm_shared/pm_materials.h | 1 + pm_shared/pm_shared.c | 24 ++-- 36 files changed, 473 insertions(+), 123 deletions(-) diff --git a/common/const.h b/common/const.h index b885e44e..d29816e6 100644 --- a/common/const.h +++ b/common/const.h @@ -110,7 +110,9 @@ #define EF_NOINTERP 32 // don't interpolate the next frame #define EF_LIGHT 64 // rocket flare glow sprite #define EF_NODRAW 128 // don't draw entity - +#define EF_NIGHTVISION 256 // player nightvision +#define EF_SNIPERLASER 512 // sniper laser effect +#define EF_FIBERCAMERA 1024 // fiber camera #define EF_NOREFLECT (1<<24) // Entity won't reflecting in mirrors @@ -531,6 +533,7 @@ #define TEFIRE_FLAG_LOOP 4 // if set, sprite plays at 15 fps, otherwise plays at whatever rate stretches the animation over the sprite's duration. #define TEFIRE_FLAG_ALPHA 8 // if set, sprite is rendered alpha blended at 50% else, opaque #define TEFIRE_FLAG_PLANAR 16 // if set, all fire sprites have same initial Z instead of randomly filling a cube. +#define TEFIRE_FLAG_ADDITIVE 32 // if set, sprite is rendered non-opaque with additive #define TE_PLAYERATTACHMENT 124 // attaches a TENT to a player (this is a high-priority tent) // byte (entity index of player) @@ -621,8 +624,9 @@ #define CHAN_BODY 4 #define CHAN_STREAM 5 // allocate stream channel from the static or dynamic area #define CHAN_STATIC 6 // allocate channel from the static area -#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network +#define CHAN_NETWORKVOICE_BASE 7 // voice data coming across the network #define CHAN_NETWORKVOICE_END 500 // network voice data reserves slots (CHAN_NETWORKVOICE_BASE through CHAN_NETWORKVOICE_END). +#define CHAN_BOT 501 // channel used for bot chatter. // attenuation values #define ATTN_NONE 0 @@ -724,7 +728,8 @@ enum kRenderFxDeadPlayer, // kRenderAmt is the player index kRenderFxExplode, // Scale up really big! kRenderFxGlowShell, // Glowing Shell - kRenderFxClampMinScale // Keep this sprite from getting very small (SPRITES only!) + kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!) + kRenderFxLightMultiplier //CTM !!!CZERO added to tell the studiorender that the value in iuser2 is a lightmultiplier }; typedef unsigned int func_t; diff --git a/common/cvardef.h b/common/cvardef.h index f822cc7a..c57b97a7 100644 --- a/common/cvardef.h +++ b/common/cvardef.h @@ -24,6 +24,7 @@ #define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server. #define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ). #define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log +#define FCVAR_NOEXTRAWHITEPACE (1<<9) // strip trailing/leading white space from this cvar typedef struct cvar_s { @@ -34,4 +35,4 @@ typedef struct cvar_s struct cvar_s *next; } cvar_t; -#endif//CVARDEF_H \ No newline at end of file +#endif//CVARDEF_H diff --git a/dlls/buttons.cpp b/dlls/buttons.cpp index 7b050add..3027f10e 100644 --- a/dlls/buttons.cpp +++ b/dlls/buttons.cpp @@ -1045,7 +1045,11 @@ void CMomentaryRotButton::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, US pev->ideal_yaw = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles, m_start ) / m_flMoveDistance; UpdateAllButtons( pev->ideal_yaw, 1 ); - UpdateTarget( pev->ideal_yaw ); + + // Calculate destination angle and use it to predict value, this prevents sending target in wrong direction on retriggering + Vector dest = pev->angles + pev->avelocity * ( pev->nextthink - pev->ltime ); + float value1 = CBaseToggle::AxisDelta( pev->spawnflags, dest, m_start ) / m_flMoveDistance; + UpdateTarget( value1 ); } void CMomentaryRotButton::UpdateAllButtons( float value, int start ) diff --git a/dlls/cbase.h b/dlls/cbase.h index 47ce7595..617bbab9 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -280,8 +280,8 @@ public: #ifdef _DEBUG void FunctionCheck( void *pFunction, char *name ) { - if( pFunction && !NAME_FOR_FUNCTION( (unsigned long)( pFunction ) ) ) - ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING( pev->classname ), name, (unsigned long)pFunction ); + if( pFunction && !NAME_FOR_FUNCTION( (size_t)( pFunction ) ) ) + ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING( pev->classname ), name, (size_t)pFunction ); } BASEPTR ThinkSet( BASEPTR func, char *name ) diff --git a/dlls/client.cpp b/dlls/client.cpp index 5fb7c221..74be0ea3 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -48,6 +48,8 @@ extern void CopyToBodyQue( entvars_t* pev ); extern int giPrecacheGrunt; extern int gmsgSayText; +extern cvar_t allow_spectators; + extern int g_teamplay; void LinkUserMessages( void ); @@ -204,6 +206,97 @@ void ClientPutInServer( edict_t *pEntity ) #include "voice_gamemgr.h" extern CVoiceGameMgr g_VoiceGameMgr; #endif + +//----------------------------------------------------------------------------- +// Purpose: determine if a uchar32 represents a valid Unicode code point +//----------------------------------------------------------------------------- +bool Q_IsValidUChar32( unsigned int uVal ) +{ + // Values > 0x10FFFF are explicitly invalid; ditto for UTF-16 surrogate halves, + // values ending in FFFE or FFFF, or values in the 0x00FDD0-0x00FDEF reserved range + return ( uVal < 0x110000u ) && ( ( uVal - 0x00D800u ) > 0x7FFu ) && ( ( uVal & 0xFFFFu ) < 0xFFFEu ) && ( ( uVal - 0x00FDD0u ) > 0x1Fu ); +} + +// Decode one character from a UTF-8 encoded string. Treats 6-byte CESU-8 sequences +// as a single character, as if they were a correctly-encoded 4-byte UTF-8 sequence. +int Q_UTF8ToUChar32( const char *pUTF8_, unsigned int &uValueOut, bool &bErrorOut ) +{ + const unsigned char *pUTF8 = (const unsigned char*)pUTF8_; + + int nBytes = 1; + unsigned int uValue = pUTF8[0]; + unsigned int uMinValue = 0; + + // 0....... single byte + if( uValue < 0x80 ) + goto decodeFinishedNoCheck; + + // Expecting at least a two-byte sequence with 0xC0 <= first <= 0xF7 (110...... and 11110...) + if( ( uValue - 0xC0u ) > 0x37u || ( pUTF8[1] & 0xC0 ) != 0x80 ) + goto decodeError; + + uValue = ( uValue << 6 ) - ( 0xC0 << 6 ) + pUTF8[1] - 0x80; + nBytes = 2; + uMinValue = 0x80; + + // 110..... two-byte lead byte + if( !( uValue & ( 0x20 << 6 ) ) ) + goto decodeFinished; + + // Expecting at least a three-byte sequence + if( ( pUTF8[2] & 0xC0 ) != 0x80 ) + goto decodeError; + + uValue = ( uValue << 6 ) - ( 0x20 << 12 ) + pUTF8[2] - 0x80; + nBytes = 3; + uMinValue = 0x800; + + // 1110.... three-byte lead byte +decodeFinished: + if( uValue >= uMinValue && Q_IsValidUChar32( uValue ) ) + { +decodeFinishedNoCheck: + uValueOut = uValue; + bErrorOut = false; + return nBytes; + } +decodeError: + uValueOut = '?'; + bErrorOut = true; + return nBytes; + +decodeFinishedMaybeCESU8: + // Do we have a full UTF-16 surrogate pair that's been UTF-8 encoded afterwards? + // That is, do we have 0xD800-0xDBFF followed by 0xDC00-0xDFFF? If so, decode it all. + if( ( uValue - 0xD800u ) < 0x400u && pUTF8[3] == 0xED && (unsigned char)( pUTF8[4] - 0xB0 ) < 0x10 && ( pUTF8[5] & 0xC0 ) == 0x80 ) + { + uValue = 0x10000 + ( ( uValue - 0xD800u ) << 10 ) + ( (unsigned char)( pUTF8[4] - 0xB0 ) << 6 ) + pUTF8[5] - 0x80; + nBytes = 6; + uMinValue = 0x10000; + } + goto decodeFinished; +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if UTF-8 string contains invalid sequences. +//----------------------------------------------------------------------------- +bool Q_UnicodeValidate( const char *pUTF8 ) +{ + bool bError = false; + while( *pUTF8 ) + { + unsigned int uVal; + // Our UTF-8 decoder silently fixes up 6-byte CESU-8 (improperly re-encoded UTF-16) sequences. + // However, these are technically not valid UTF-8. So if we eat 6 bytes at once, it's an error. + int nCharSize = Q_UTF8ToUChar32( pUTF8, uVal, bError ); + if( bError || nCharSize == 6 ) + return false; + pUTF8 += nCharSize; + } + return true; +} + + //// HOST_SAY // String comes in as // say blah blah blah @@ -265,20 +358,13 @@ void Host_Say( edict_t *pEntity, int teamonly ) p[strlen( p ) - 1] = 0; } - // make sure the text has content - for( pc = p; pc != NULL && *pc != 0; pc++ ) - { - if( !isspace( *pc ) ) - { - pc = NULL; // we've found an alphanumeric character, so text is valid - break; - } - } - if( pc != NULL ) + if( !p || !p[0] || !Q_UnicodeValidate ( p ) ) return; // no character found, so say nothing // turn on color set 2 (color on, no sound) - if( teamonly ) + if( player->IsObserver() && ( teamonly ) ) + sprintf( text, "%c(SPEC) %s: ", 2, STRING( pEntity->v.netname ) ); + else if( teamonly ) sprintf( text, "%c(TEAM) %s: ", 2, STRING( pEntity->v.netname ) ); else sprintf( text, "%c%s: ", 2, STRING( pEntity->v.netname ) ); @@ -313,9 +399,14 @@ void Host_Say( edict_t *pEntity, int teamonly ) if( g_VoiceGameMgr.PlayerHasBlockedPlayer( client, player ) ) continue; #endif - if( teamonly && g_pGameRules->PlayerRelationship( client, CBaseEntity::Instance( pEntity ) ) != GR_TEAMMATE ) + if( !player->IsObserver() && teamonly && g_pGameRules->PlayerRelationship( client, CBaseEntity::Instance( pEntity ) ) != GR_TEAMMATE ) continue; + // Spectators can only talk to other specs + if( player->IsObserver() && teamonly ) + if ( !client->IsObserver() ) + continue; + MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, client->pev ); WRITE_BYTE( ENTINDEX( pEntity ) ); WRITE_STRING( text ); @@ -459,12 +550,40 @@ void ClientCommand( edict_t *pEntity ) { GetClassPtr( (CBasePlayer *)pev )->SelectLastItem(); } - else if( FStrEq( pcmd, "spectate" ) && ( pev->flags & FL_PROXY ) ) // added for proxy support + else if( FStrEq( pcmd, "spectate" ) // clients wants to become a spectator { - CBasePlayer * pPlayer = GetClassPtr( (CBasePlayer *)pev ); + // always allow proxies to become a spectator + if( ( pev->flags & FL_PROXY ) || allow_spectators.value ) + { + CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev ); - edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer ); - pPlayer->StartObserver( pev->origin, VARS( pentSpawnSpot )->angles ); + edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer ); + pPlayer->StartObserver( pev->origin, VARS( pentSpawnSpot )->angles ); + + // notify other clients of player switching to spectator mode + UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s switched to spectator mode\n", + ( pev->netname && STRING(pev->netname)[0] != 0 ) ? STRING(pev->netname) : "unconnected" ) ); + } + else + ClientPrint( pev, HUD_PRINTCONSOLE, "Spectator mode is disabled.\n" ); + } + else if( FStrEq( pcmd, "specmode" ) ) // new spectator mode + { + CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev ); + + if( pPlayer->IsObserver() ) + pPlayer->Observer_SetMode( atoi( CMD_ARGV( 1 ) ) ); + } + else if( FStrEq( pcmd, "closemenus" ) ) + { + // just ignore it + } + else if( FStrEq( pcmd, "follownext" ) ) // follow next player + { + CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev ); + + if( pPlayer->IsObserver() ) + pPlayer->Observer_FindNextPlayer( atoi( CMD_ARGV( 1 ) ) ? true : false ); } else if( g_pGameRules->ClientCommand( GetClassPtr( (CBasePlayer *)pev ), pcmd ) ) { @@ -524,12 +643,15 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) // Set the name g_engfuncs.pfnSetClientKeyValue( ENTINDEX( pEntity ), infobuffer, "name", sName ); - char text[256]; - snprintf( text, 256, "* %s changed name to %s\n", STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); - MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); - WRITE_BYTE( ENTINDEX( pEntity ) ); - WRITE_STRING( text ); - MESSAGE_END(); + if( gpGlobals->maxClients > 1 ) + { + char text[256]; + snprintf( text, 256, "* %s changed name to %s\n", STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); + MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); + WRITE_BYTE( ENTINDEX( pEntity ) ); + WRITE_STRING( text ); + MESSAGE_END(); + } // team match? if( g_teamplay ) @@ -983,7 +1105,7 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h int i; // don't send if flagged for NODRAW and it's not the host getting the message - if( ( ent->v.effects == EF_NODRAW ) && ( ent != host ) ) + if( ( ent->v.effects & EF_NODRAW ) && ( ent != host ) ) return 0; // Ignore ents without valid / visible models @@ -1553,41 +1675,67 @@ engine sets cd to 0 before calling. */ void UpdateClientData( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ) { - cd->flags = ent->v.flags; - cd->health = ent->v.health; + if( !ent || !ent->pvPrivateData ) + return; + entvars_t *pev = (entvars_t *)&ent->v; + CBasePlayer *pl = (CBasePlayer *)( CBasePlayer::Instance( pev ) ); + entvars_t *pevOrg = NULL; - cd->viewmodel = MODEL_INDEX( STRING( ent->v.viewmodel ) ); + // if user is spectating different player in First person, override some vars + if( pl && pl->pev->iuser1 == OBS_IN_EYE ) + { + if( pl->m_hObserverTarget ) + { + pevOrg = pev; + pev = pl->m_hObserverTarget->pev; + pl = (CBasePlayer *)(CBasePlayer::Instance( pev ) ); + } + } - cd->waterlevel = ent->v.waterlevel; - cd->watertype = ent->v.watertype; - cd->weapons = ent->v.weapons; + cd->flags = pev->flags; + cd->health = pev->health; + + cd->viewmodel = MODEL_INDEX( STRING( pev->viewmodel ) ); + + cd->waterlevel = pev->waterlevel; + cd->watertype = pev->watertype; + cd->weapons = pev->weapons; // Vectors - cd->origin = ent->v.origin; - cd->velocity = ent->v.velocity; - cd->view_ofs = ent->v.view_ofs; - cd->punchangle = ent->v.punchangle; + cd->origin = pev->origin; + cd->velocity = pev->velocity; + cd->view_ofs = pev->view_ofs; + cd->punchangle = pev->punchangle; - cd->bInDuck = ent->v.bInDuck; - cd->flTimeStepSound = ent->v.flTimeStepSound; - cd->flDuckTime = ent->v.flDuckTime; - cd->flSwimTime = ent->v.flSwimTime; - cd->waterjumptime = ent->v.teleport_time; + cd->bInDuck = pev->bInDuck; + cd->flTimeStepSound = pev->flTimeStepSound; + cd->flDuckTime = pev->flDuckTime; + cd->flSwimTime = pev->flSwimTime; + cd->waterjumptime = pev->teleport_time; strcpy( cd->physinfo, ENGINE_GETPHYSINFO( ent ) ); - cd->maxspeed = ent->v.maxspeed; - cd->fov = ent->v.fov; - cd->weaponanim = ent->v.weaponanim; + cd->maxspeed = pev->maxspeed; + cd->fov = pev->fov; + cd->weaponanim = pev->weaponanim; - cd->pushmsec = ent->v.pushmsec; + cd->pushmsec = pev->pushmsec; + // Spectator mode + if( pevOrg != NULL ) + { + // don't use spec vars from chased player + cd->iuser1 = pevOrg->iuser1; + cd->iuser2 = pevOrg->iuser2; + } + else + { + cd->iuser1 = pev->iuser1; + cd->iuser2 = pev->iuser2; + } #if defined( CLIENT_WEAPONS ) if( sendweapons ) { - entvars_t *pev = (entvars_t *)&ent->v; - CBasePlayer *pl = (CBasePlayer *)CBasePlayer::Instance( pev ); - if( pl ) { cd->m_flNextAttack = pl->m_flNextAttack; diff --git a/dlls/crossbow.cpp b/dlls/crossbow.cpp index 45fd922c..7a4686e7 100644 --- a/dlls/crossbow.cpp +++ b/dlls/crossbow.cpp @@ -353,7 +353,7 @@ void CCrossbow::PrimaryAttack( void ) // this function only gets called in multiplayer void CCrossbow::FireSniperBolt() { - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.75 ); if( m_iClip == 0 ) { @@ -451,7 +451,7 @@ void CCrossbow::FireBolt() // HEV suit - indicate out of ammo condition m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.75 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75; diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index 94f0066b..80a18d65 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -27,7 +27,7 @@ LINK_ENTITY_TO_CLASS( weapon_crowbar, CCrowbar ) -enum gauss_e +enum crowbar_e { CROWBAR_IDLE = 0, CROWBAR_DRAW, @@ -40,8 +40,7 @@ enum gauss_e CROWBAR_ATTACK3HIT }; - -void CCrowbar::Spawn( ) +void CCrowbar::Spawn() { Precache(); m_iId = WEAPON_CROWBAR; @@ -191,7 +190,7 @@ int CCrowbar::Swing( int fFirst ) if( fFirst ) { // miss - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); @@ -297,7 +296,7 @@ int CCrowbar::Swing( int fFirst ) m_pPlayer->m_iWeaponVolume = flVol * CROWBAR_WALLHIT_VOLUME; #endif - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.25; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.25 ); SetThink( &CCrowbar::Smack ); pev->nextthink = UTIL_WeaponTimeBase() + 0.2; diff --git a/dlls/doors.cpp b/dlls/doors.cpp index bf7205ee..bdc82f06 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -1100,19 +1100,22 @@ void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP Vector move = m_vecPosition1 + ( value * ( m_vecPosition2 - m_vecPosition1 ) ); Vector delta = move - pev->origin; - float speed = delta.Length() * 10; + //float speed = delta.Length() * 10; + float speed = delta.Length() / 0.1; // move there in 0.1 sec if( speed != 0 ) { // This entity only thinks when it moves, so if it's thinking, it's in the process of moving - // play the sound when it starts moving + // play the sound when it starts moving(not yet thinking) if( pev->nextthink < pev->ltime || pev->nextthink == 0 ) EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ), 1, ATTN_NORM ); + // If we already moving to designated point, return + else if( move == m_vecFinalDest ) + return; LinearMove( move, speed ); SetMoveDone( &CMomentaryDoor::MomentaryMoveDone ); } - } void CMomentaryDoor::MomentaryMoveDone( void ) diff --git a/dlls/extdll.h b/dlls/extdll.h index cbc7ebb9..58349e32 100644 --- a/dlls/extdll.h +++ b/dlls/extdll.h @@ -44,7 +44,7 @@ #else // _WIN32 #define FALSE 0 #define TRUE (!FALSE) -typedef unsigned long ULONG; +typedef unsigned int ULONG; typedef unsigned char BYTE; typedef int BOOL; #define MAX_PATH PATH_MAX diff --git a/dlls/game.cpp b/dlls/game.cpp index 3aec1810..fb247903 100644 --- a/dlls/game.cpp +++ b/dlls/game.cpp @@ -39,6 +39,8 @@ cvar_t teamoverride = { "mp_teamoverride","1" }; cvar_t defaultteam = { "mp_defaultteam","0" }; cvar_t allowmonsters = { "mp_allowmonsters","0", FCVAR_SERVER }; +cvar_t allow_spectators = { "allow_spectators", "0", FCVAR_SERVER }; // 0 prevents players from being spectators + cvar_t mp_chattime = { "mp_chattime","10", FCVAR_SERVER }; // Engine Cvars diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index 14aac39b..10149202 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -145,7 +145,7 @@ void CGauss::PrimaryAttack() if( m_pPlayer->pev->waterlevel == 3 ) { PlayEmptySound(); - m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15; + m_flNextSecondaryAttack = m_flNextPrimaryAttack = GetNextAttackDelay( 0.15 ); return; } @@ -183,7 +183,7 @@ void CGauss::SecondaryAttack() PlayEmptySound(); } - m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5; + m_flNextSecondaryAttack = m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); return; } diff --git a/dlls/handgrenade.cpp b/dlls/handgrenade.cpp index 063b2886..96119b6b 100644 --- a/dlls/handgrenade.cpp +++ b/dlls/handgrenade.cpp @@ -170,7 +170,7 @@ void CHandGrenade::WeaponIdle( void ) m_flReleaseThrow = 0; m_flStartThrow = 0; - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5; m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; @@ -180,7 +180,7 @@ void CHandGrenade::WeaponIdle( void ) // just threw last grenade // set attack times in the future, and weapon idle in the future so we can see the whole throw // animation, weapon idle will automatically retire the weapon for us. - m_flTimeWeaponIdle = m_flNextSecondaryAttack = m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5;// ensure that the animation can finish playing + m_flTimeWeaponIdle = m_flNextSecondaryAttack = m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 );// ensure that the animation can finish playing } return; } diff --git a/dlls/mp5.cpp b/dlls/mp5.cpp index 7d05d5e1..7131f888 100644 --- a/dlls/mp5.cpp +++ b/dlls/mp5.cpp @@ -177,7 +177,7 @@ void CMP5::PrimaryAttack() // HEV suit - indicate out of ammo condition m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.1 ); if( m_flNextPrimaryAttack < UTIL_WeaponTimeBase() ) m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1; @@ -227,7 +227,7 @@ void CMP5::SecondaryAttack( void ) #endif PLAYBACK_EVENT( flags, m_pPlayer->edict(), m_usMP52 ); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1; + m_flNextPrimaryAttack = GetNextAttackDelay( 1 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5;// idle pretty soon after shooting. diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 929c2bf6..ebef51de 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -92,7 +92,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() if( IS_DEDICATED_SERVER() ) { // dedicated server - char *servercfgfile = (char *)CVAR_GET_STRING( "servercfgfile" ); + /*char *servercfgfile = (char *)CVAR_GET_STRING( "servercfgfile" ); if( servercfgfile && servercfgfile[0] ) { @@ -102,6 +102,8 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() sprintf( szCommand, "exec %s\n", servercfgfile ); SERVER_COMMAND( szCommand ); } + */ + // this code has been moved into engine, to only run server.cfg once } else { diff --git a/dlls/nihilanth.cpp b/dlls/nihilanth.cpp index 58317b3c..ba1c6192 100644 --- a/dlls/nihilanth.cpp +++ b/dlls/nihilanth.cpp @@ -1185,8 +1185,22 @@ void CNihilanth::CommandUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_ case USE_OFF: { CBaseEntity *pTouch = UTIL_FindEntityByTargetname( NULL, m_szDeadTouch ); - if( pTouch && m_hEnemy != NULL ) - pTouch->Touch( m_hEnemy ); + if( pTouch ) + { + if( m_hEnemy != NULL ) + { + pTouch->Touch( m_hEnemy ); + } + // if the player is using "notarget", the ending sequence won't fire unless we catch it here + else + { + CBaseEntity *pEntity = UTIL_FindEntityByClassname( NULL, "player" ); + if( pEntity != NULL && pEntity->IsAlive() ) + { + pTouch->Touch( pEntity ); + } + } + } } break; case USE_ON: diff --git a/dlls/player.cpp b/dlls/player.cpp index 2f097072..7d7363b5 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -34,6 +34,7 @@ #include "decals.h" #include "gamerules.h" #include "game.h" +#include "pm_shared.h" #include "hltv.h" // #define DUCKFIX @@ -201,7 +202,8 @@ void LinkUserMessages( void ) gmsgDamage = REG_USER_MSG( "Damage", 12 ); gmsgBattery = REG_USER_MSG( "Battery", 2); gmsgTrain = REG_USER_MSG( "Train", 1 ); - gmsgHudText = REG_USER_MSG( "HudText", -1 ); + //gmsgHudText = REG_USER_MSG( "HudTextPro", -1 ); + gmsgHudText = REG_USER_MSG( "HudText", -1 ); // we don't use the message but 3rd party addons may! gmsgSayText = REG_USER_MSG( "SayText", -1 ); gmsgTextMsg = REG_USER_MSG( "TextMsg", -1 ); gmsgWeaponList = REG_USER_MSG( "WeaponList", -1 ); @@ -785,6 +787,12 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit ) m_pLastItem = NULL; + if( m_pTank != NULL ) + { + m_pTank->Use( this, this, USE_OFF, 0 ); + m_pTank = NULL; + } + int i; CBasePlayerItem *pPendingItem; for( i = 0; i < MAX_ITEM_TYPES; i++ ) @@ -1297,6 +1305,9 @@ void CBasePlayer::PlayerDeathThink( void ) StartDeathCam(); } + if( pev->iuser1 ) // player is in spectator mode + return; + // wait for any button down, or mp_forcerespawn is set and the respawn time is up if( !fAnyButtonDown && !( g_pGameRules->IsMultiplayer() && forcerespawn.value > 0 && ( gpGlobals->time > ( m_fDeadTime + 5 ) ) ) ) return; @@ -1345,7 +1356,9 @@ void CBasePlayer::StartDeathCam( void ) } CopyToBodyQue( pev ); - StartObserver( pSpot->v.origin, pSpot->v.v_angle ); + + UTIL_SetOrigin( pev, pSpot->v.origin ); + pev->angles = pev->v_angle = pSpot->v.v_angle; } else { @@ -1353,23 +1366,89 @@ void CBasePlayer::StartDeathCam( void ) TraceResult tr; CopyToBodyQue( pev ); UTIL_TraceLine( pev->origin, pev->origin + Vector( 0, 0, 128 ), ignore_monsters, edict(), &tr ); - StartObserver( tr.vecEndPos, UTIL_VecToAngles( tr.vecEndPos - pev->origin ) ); - return; + + UTIL_SetOrigin( pev, tr.vecEndPos ); + pev->angles = pev->v_angle = UTIL_VecToAngles( tr.vecEndPos - pev->origin ); } + + // start death cam + m_afPhysicsFlags |= PFLAG_OBSERVER; + pev->view_ofs = g_vecZero; + pev->fixangle = TRUE; + pev->solid = SOLID_NOT; + pev->takedamage = DAMAGE_NO; + pev->movetype = MOVETYPE_NONE; + pev->modelindex = 0; } void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) { - m_afPhysicsFlags |= PFLAG_OBSERVER; + // clear any clientside entities attached to this player + MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); + WRITE_BYTE( TE_KILLPLAYERATTACHMENTS ); + WRITE_BYTE( (BYTE)entindex() ); + MESSAGE_END(); + // Holster weapon immediately, to allow it to cleanup + if( m_pActiveItem ) + m_pActiveItem->Holster(); + + if( m_pTank != NULL ) + { + m_pTank->Use( this, this, USE_OFF, 0 ); + m_pTank = NULL; + } + + // clear out the suit message cache so we don't keep chattering + SetSuitUpdate( NULL, FALSE, 0 ); + + // Tell Ammo Hud that the player is dead + MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); + WRITE_BYTE( 0 ); + WRITE_BYTE( 0XFF ); + WRITE_BYTE( 0xFF ); + MESSAGE_END(); + + // reset FOV + m_iFOV = m_iClientFOV = 0; + pev->fov = m_iFOV; + MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); + WRITE_BYTE( 0 ); + MESSAGE_END(); + + // Setup flags + m_iHideHUD = ( HIDEHUD_HEALTH | HIDEHUD_WEAPONS ); + m_afPhysicsFlags |= PFLAG_OBSERVER; + pev->effects = EF_NODRAW; pev->view_ofs = g_vecZero; pev->angles = pev->v_angle = vecViewAngle; pev->fixangle = TRUE; pev->solid = SOLID_NOT; pev->takedamage = DAMAGE_NO; pev->movetype = MOVETYPE_NONE; - pev->modelindex = 0; + ClearBits( m_afPhysicsFlags, PFLAG_DUCKING ); + ClearBits( pev->flags, FL_DUCKING ); + pev->deadflag = DEAD_RESPAWNABLE; + pev->health = 1; + + // Clear out the status bar + m_fInitHUD = TRUE; + + pev->team = 0; + MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); + WRITE_BYTE( ENTINDEX(edict()) ); + WRITE_STRING( "" ); + MESSAGE_END(); + + // Remove all the player's stuff + RemoveAllItems( FALSE ); + + // Move them to the new position UTIL_SetOrigin( pev, vecPosition ); + + // Find a player to watch + m_flNextObserverInput = 0; + Observer_SetMode( m_iObserverLastMode ); } // @@ -1379,6 +1458,9 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) void CBasePlayer::PlayerUse( void ) { + if( IsObserver() ) + return; + // Was use pressed or released? if( !( ( pev->button | m_afButtonPressed | m_afButtonReleased) & IN_USE ) ) return; @@ -1747,6 +1829,16 @@ void CBasePlayer::PreThink( void ) CheckSuitUpdate(); + // Observer Button Handling + if( IsObserver() ) + { + Observer_HandleButtons(); + Observer_CheckTarget(); + Observer_CheckProperties(); + pev->impulse = 0; + return; + } + if( pev->deadflag >= DEAD_DYING ) { PlayerDeathThink(); @@ -3767,6 +3859,9 @@ void CBasePlayer::UpdateClientData( void ) g_pGameRules->InitHUD( this ); m_fGameHUDInitialized = TRUE; + + m_iObserverLastMode = OBS_ROAMING; + if( g_pGameRules->IsMultiplayer() ) { FireTargets( "game_playerjoin", this, this, USE_TOGGLE, 0 ); @@ -3807,7 +3902,10 @@ void CBasePlayer::UpdateClientData( void ) if( pev->health != m_iClientHealth ) { - int iHealth = max( pev->health, 0 ); // make sure that no negative health values are sent +#define clamp( val, min, max ) ( ((val) > (max)) ? (max) : ( ((val) < (min)) ? (min) : (val) ) ) + int iHealth = clamp( pev->health, 0, 255 ); // make sure that no negative health values are sent + if( pev->health > 0.0f && pev->health <= 1.0f ) + iHealth = 1; // send "health" update message MESSAGE_BEGIN( MSG_ONE, gmsgHealth, NULL, pev ); @@ -4336,7 +4434,8 @@ void CBasePlayer::DropPlayerItem( char *pszItemName ) // item we want to drop and hit a BREAK; pWeapon is the item. if( pWeapon ) { - g_pGameRules->GetNextBestWeapon( this, pWeapon ); + if( !g_pGameRules->GetNextBestWeapon( this, pWeapon ) ) + return; // can't drop the item they asked for, may be our last item or something we can't holster UTIL_MakeVectors( pev->angles ); diff --git a/dlls/player.h b/dlls/player.h index e75787ee..cb2bddf8 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -86,6 +86,18 @@ enum sbar_data class CBasePlayer : public CBaseMonster { public: + // Spectator camera + void Observer_FindNextPlayer( bool bReverse ); + void Observer_HandleButtons(); + void Observer_SetMode( int iMode ); + void Observer_CheckTarget(); + void Observer_CheckProperties(); + EHANDLE m_hObserverTarget; + float m_flNextObserverInput; + int m_iObserverWeapon; // weapon of current tracked target + int m_iObserverLastMode;// last used observer mode + int IsObserver() { return pev->iuser1; }; + int random_seed; // See that is shared between client & server for shared weapons code int m_iPlayerSound;// the index of the sound list slot reserved for this player diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index 1fec5cf1..95c9132a 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -297,7 +297,7 @@ void CRpg::Reload( void ) // Set the next attack time into the future so that WeaponIdle will get called more often // than reload, allowing the RPG LTD to be updated - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); if( m_cActiveRockets && m_fSpotActive ) { @@ -463,7 +463,7 @@ void CRpg::PrimaryAttack() m_iClip--; - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.5; + m_flNextPrimaryAttack = GetNextAttackDelay( 1.5 ); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.5; } else diff --git a/dlls/satchel.cpp b/dlls/satchel.cpp index 48ec5b9a..05d1fc8c 100644 --- a/dlls/satchel.cpp +++ b/dlls/satchel.cpp @@ -354,7 +354,7 @@ void CSatchel::PrimaryAttack() } m_chargeReady = 2; - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5; break; @@ -401,7 +401,7 @@ void CSatchel::Throw( void ) m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.0; + m_flNextPrimaryAttack = GetNextAttackDelay( 1.0 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5; } } @@ -442,7 +442,7 @@ void CSatchel::WeaponIdle( void ) // use tripmine animations strcpy( m_pPlayer->m_szAnimExtention, "trip" ); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5; m_chargeReady = 0; break; diff --git a/dlls/saverestore.h b/dlls/saverestore.h index f76613e8..a9ad2c54 100644 --- a/dlls/saverestore.h +++ b/dlls/saverestore.h @@ -59,7 +59,7 @@ public: void WriteVector( const char *pname, const float *value, int count ); // Save a vector void WritePositionVector( const char *pname, const Vector &value ); // Offset for landmark if necessary void WritePositionVector( const char *pname, const float *value, int count ); // array of pos vectors - void WriteFunction( const char *pname, const int *value, int count ); // Save a function pointer + void WriteFunction( const char *pname, void **value, int count ); // Save a function pointer int WriteEntVars( const char *pname, entvars_t *pev ); // Save entvars_t (entvars_t) int WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); diff --git a/dlls/shotgun.cpp b/dlls/shotgun.cpp index 8c96e99c..595561e2 100644 --- a/dlls/shotgun.cpp +++ b/dlls/shotgun.cpp @@ -119,7 +119,7 @@ void CShotgun::PrimaryAttack() if( m_pPlayer->pev->waterlevel == 3 ) { PlayEmptySound(); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.15 ); return; } @@ -172,7 +172,7 @@ void CShotgun::PrimaryAttack() if( m_iClip != 0 ) m_flPumpTime = gpGlobals->time + 0.5; - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.75 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75; if( m_iClip != 0 ) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5.0; @@ -187,7 +187,7 @@ void CShotgun::SecondaryAttack( void ) if( m_pPlayer->pev->waterlevel == 3 ) { PlayEmptySound(); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.15; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.15 ); return; } @@ -243,7 +243,7 @@ void CShotgun::SecondaryAttack( void ) if( m_iClip != 0 ) m_flPumpTime = gpGlobals->time + 0.95; - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.5; + m_flNextPrimaryAttack = GetNextAttackDelay( 1.5 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.5; if( m_iClip != 0 ) m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 6.0; @@ -269,7 +269,7 @@ void CShotgun::Reload( void ) m_fInSpecialReload = 1; m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.6; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.6; - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.0; + m_flNextPrimaryAttack = GetNextAttackDelay( 1.0 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.0; return; } diff --git a/dlls/squeakgrenade.cpp b/dlls/squeakgrenade.cpp index 22200b74..30ddda62 100644 --- a/dlls/squeakgrenade.cpp +++ b/dlls/squeakgrenade.cpp @@ -533,7 +533,7 @@ void CSqueak::PrimaryAttack() m_fJustThrown = 1; - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.3; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.3 ); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0; } } diff --git a/dlls/subs.cpp b/dlls/subs.cpp index bc7baf18..5ebe757b 100644 --- a/dlls/subs.cpp +++ b/dlls/subs.cpp @@ -415,6 +415,14 @@ After moving, set origin to exact final destination, call "move done" function */ void CBaseToggle::LinearMoveDone( void ) { + Vector delta = m_vecFinalDest - pev->origin; + float error = delta.Length(); + if( error > 0.03125 ) + { + LinearMove( m_vecFinalDest, 100 ); + return; + } + UTIL_SetOrigin( pev, m_vecFinalDest ); pev->velocity = g_vecZero; pev->nextthink = -1; diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index d7f9483c..958f899f 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -688,7 +688,7 @@ void PlayCDTrack( int iTrack ) if( iTrack == -1 ) { - CLIENT_COMMAND( pClient, "cd pause\n" ); + CLIENT_COMMAND( pClient, "cd stop\n" ); } else { diff --git a/dlls/tripmine.cpp b/dlls/tripmine.cpp index f04d906a..e2ed0817 100644 --- a/dlls/tripmine.cpp +++ b/dlls/tripmine.cpp @@ -470,7 +470,7 @@ void CTripmine::PrimaryAttack( void ) }*/ - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.3; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.3 ); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); } diff --git a/dlls/util.cpp b/dlls/util.cpp index d1fceb0a..4fc0d51a 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1886,7 +1886,7 @@ void CSave::WritePositionVector( const char *pname, const float *value, int coun } } -void CSave::WriteFunction( const char *pname, const int *data, int count ) +void CSave::WriteFunction( const char *pname, void **data, int count ) { const char *functionName; @@ -2042,7 +2042,7 @@ int CSave::WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFi WriteInt( pTest->fieldName, (int *)(char *)pOutputData, pTest->fieldSize ); break; case FIELD_FUNCTION: - WriteFunction( pTest->fieldName, (int *)pOutputData, pTest->fieldSize ); + WriteFunction( pTest->fieldName, (void **)pOutputData, pTest->fieldSize ); break; default: ALERT( at_error, "Bad field type\n" ); diff --git a/dlls/util.h b/dlls/util.h index e8aee878..f8ae0b6a 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -37,7 +37,7 @@ extern globalvars_t *gpGlobals; #define STRING(offset) (const char *)(gpGlobals->pStringBase + (int)offset) #if !defined __amd64__ || defined(CLIENT_DLL) -#define MAKE_STRING(str) ((int)(size_t)str - (int)(size_t)STRING(0)) +#define MAKE_STRING(str) ((size_t)str - (size_t)STRING(0)) #else #define MAKE_STRING ALLOC_STRING #endif diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index ff03bbfc..ee2a8547 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -612,6 +612,11 @@ void CBasePlayerWeapon::ItemPostFrame( void ) m_fInReload = FALSE; } + if( !(m_pPlayer->pev->button & IN_ATTACK ) ) + { + m_flLastFireTime = 0.0f; + } + if( ( m_pPlayer->pev->button & IN_ATTACK2 ) && CanAttack( m_flNextSecondaryAttack, gpGlobals->time, UseDecrement() ) ) { if( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] ) @@ -943,6 +948,7 @@ BOOL CBasePlayerWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, i m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0; + m_flLastFireTime = 0.0f; return TRUE; } @@ -1130,6 +1136,36 @@ void CBasePlayerWeapon::RetireWeapon( void ) g_pGameRules->GetNextBestWeapon( m_pPlayer, this ); } +//========================================================================= +// GetNextAttackDelay - An accurate way of calcualting the next attack time. +//========================================================================= +float CBasePlayerWeapon::GetNextAttackDelay( float delay ) +{ + if( m_flLastFireTime == 0 || m_flNextPrimaryAttack == -1 ) + { + // At this point, we are assuming that the client has stopped firing + // and we are going to reset our book keeping variables. + m_flLastFireTime = gpGlobals->time; + m_flPrevPrimaryAttack = delay; + } + // calculate the time between this shot and the previous + float flTimeBetweenFires = gpGlobals->time - m_flLastFireTime; + float flCreep = 0.0f; + if( flTimeBetweenFires > 0 ) + flCreep = flTimeBetweenFires - m_flPrevPrimaryAttack; // postive or negative + + // save the last fire time + m_flLastFireTime = gpGlobals->time; + + float flNextAttack = UTIL_WeaponTimeBase() + delay - flCreep; + // we need to remember what the m_flNextPrimaryAttack time is set to for each shot, + // store it as m_flPrevPrimaryAttack. + m_flPrevPrimaryAttack = flNextAttack - UTIL_WeaponTimeBase(); + //char szMsg[256]; + //_snprintf( szMsg, sizeof(szMsg), "next attack time: %0.4f\n", gpGlobals->time + flNextAttack ); + //OutputDebugString( szMsg ); + return flNextAttack; +} //********************************************************* // weaponbox code: //********************************************************* diff --git a/dlls/weapons.h b/dlls/weapons.h index 5112254a..3e6fc5ce 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -331,6 +331,7 @@ public: void PrintState( void ); virtual CBasePlayerItem *GetWeaponPtr( void ) { return (CBasePlayerItem *)this; }; + float GetNextAttackDelay( float delay ); float m_flPumpTime; int m_fInSpecialReload; // Are we in the middle of a reload for the shotguns @@ -345,6 +346,10 @@ public: int m_fInReload; // Are we in the middle of a reload; int m_iDefaultAmmo;// how much ammo you get when you pick up this weapon as placed by a level designer. + + // hle time creep vars + float m_flPrevPrimaryAttack; + float m_flLastFireTime; }; class CBasePlayerAmmo : public CBaseEntity diff --git a/dlls/zombie.cpp b/dlls/zombie.cpp index 7fe416c7..b20293c1 100644 --- a/dlls/zombie.cpp +++ b/dlls/zombie.cpp @@ -169,13 +169,15 @@ void CZombie::IdleSound( void ) int pitch = 95 + RANDOM_LONG( 0, 9 ); // Play a random idle sound - EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pIdleSounds ) -1 )], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG( -5, 5 ) ); + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pIdleSounds ) -1 )], 1.0, ATTN_NORM, 0, pitch ); } void CZombie::AttackSound( void ) { + int pitch = 95 + RANDOM_LONG( 0, 9 ); + // Play a random attack sound - EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG( -5, 5 ) ); + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch ); } //========================================================= diff --git a/engine/eiface.h b/engine/eiface.h index 903451f5..3419e5bd 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -57,7 +57,8 @@ typedef enum { force_exactfile, // File on client must exactly match server's file force_model_samebounds, // For model files only, the geometry must fit in the same bbox - force_model_specifybounds // For model files only, the geometry must fit in the specified bbox + force_model_specifybounds, // For model files only, the geometry must fit in the specified bbox + force_model_specifybounds_if_avail // For Steam model files only, the geometry must fit in the specified bbox (if the file is available) } FORCE_TYPE; // Returned by TraceLine @@ -88,7 +89,7 @@ typedef struct int fPlayTrack; } CDStatus; -typedef unsigned long CRC32_t; +typedef unsigned int CRC32_t; // Engine hands this to DLLs for functionality callbacks typedef struct enginefuncs_s @@ -156,7 +157,7 @@ typedef struct enginefuncs_s void (*pfnCVarSetString)( const char *szVarName, const char *szValue ); void (*pfnAlertMessage)( ALERT_TYPE atype, char *szFmt, ... ); void (*pfnEngineFprintf)( FILE *pfile, char *szFmt, ... ); - void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, long cb ); + void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, int cb ); void* (*pfnPvEntPrivateData)( edict_t *pEdict ); void (*pfnFreeEntPrivateData)( edict_t *pEdict ); const char *(*pfnSzFromIndex)( int iString ); @@ -171,8 +172,8 @@ typedef struct enginefuncs_s int (*pfnRegUserMsg)( const char *pszName, int iSize ); void (*pfnAnimationAutomove)( const edict_t* pEdict, float flTime ); void (*pfnGetBonePosition)( const edict_t* pEdict, int iBone, float *rgflOrigin, float *rgflAngles ); - unsigned long (*pfnFunctionFromName)( const char *pName ); - const char *(*pfnNameForFunction)( unsigned long function ); + unsigned int (*pfnFunctionFromName)( const char *pName ); + const char *(*pfnNameForFunction)( unsigned int function ); void (*pfnClientPrintf)( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg ); // JOHN: engine callbacks so game DLL can print messages to individual clients void (*pfnServerPrint)( const char *szMsg ); const char *(*pfnCmd_Args)( void ); // these 3 added @@ -183,7 +184,7 @@ typedef struct enginefuncs_s void (*pfnCRC32_ProcessBuffer)( CRC32_t *pulCRC, void *p, int len ); void (*pfnCRC32_ProcessByte)( CRC32_t *pulCRC, unsigned char ch ); CRC32_t (*pfnCRC32_Final)( CRC32_t pulCRC ); - long (*pfnRandomLong)( long lLow, long lHigh ); + int (*pfnRandomLong)( int lLow, int lHigh ); float (*pfnRandomFloat)( float flLow, float flHigh ); void (*pfnSetView)( const edict_t *pClient, const edict_t *pViewent ); float (*pfnTime)( void ); @@ -276,7 +277,7 @@ typedef struct KeyValueData_s char *szClassName; // in: entity classname char *szKeyName; // in: name of key char *szValue; // in: value of key - long fHandled; // out: DLL sets to true if key-value pair was understood + int fHandled; // out: DLL sets to true if key-value pair was understood } KeyValueData; @@ -354,7 +355,7 @@ typedef enum _fieldtypes FIELD_TYPECOUNT // MUST BE LAST } FIELDTYPE; -#ifndef offsetof +#if !defined(offsetof) && !defined(GNUC) #define offsetof(s,m) (size_t)&(((s *)0)->m) #endif diff --git a/engine/shake.h b/engine/shake.h index c644a476..b2e88a33 100644 --- a/engine/shake.h +++ b/engine/shake.h @@ -36,7 +36,7 @@ extern int gmsgFade; #define FFADE_OUT 0x0001 // Fade out (not in) #define FFADE_MODULATE 0x0002 // Modulate (don't blend) #define FFADE_STAYOUT 0x0004 // ignores the duration, stays faded out until new ScreenFade message received - +#define FFADE_LONGFADE 0x0008 // used to indicate the fade can be longer than 16 seconds (added for czero) // This structure is sent over the net to describe a screen fade event typedef struct @@ -47,4 +47,4 @@ typedef struct byte r, g, b, a; // fade to color ( max alpha ) } ScreenFade; -#endif // SHAKE_H \ No newline at end of file +#endif // SHAKE_H diff --git a/engine/studio.h b/engine/studio.h index b5b709bb..cd572419 100644 --- a/engine/studio.h +++ b/engine/studio.h @@ -33,14 +33,14 @@ Studio models are position independent, so the cache manager can move them. // studio limits #define MAXSTUDIOTRIANGLES 32768 // max triangles per model #define MAXSTUDIOVERTS 4096 // max vertices per submodel -#define MAXSTUDIOSEQUENCES 256 // total animation sequences +#define MAXSTUDIOSEQUENCES 2048 // total animation sequences #define MAXSTUDIOSKINS 256 // total textures #define MAXSTUDIOSRCBONES 512 // bones allowed at source movement #define MAXSTUDIOBONES 128 // total bones actually used #define MAXSTUDIOMODELS 32 // sub-models per model #define MAXSTUDIOBODYPARTS 32 // body parts per submodel #define MAXSTUDIOGROUPS 16 // sequence groups (e.g. barney01.mdl, barney02.mdl, e.t.c) -#define MAXSTUDIOANIMATIONS 512 // max frames per sequence +#define MAXSTUDIOANIMATIONS 2048 // max frames per sequence #define MAXSTUDIOMESHES 256 // max textures per model #define MAXSTUDIOEVENTS 1024 // events per model #define MAXSTUDIOPIVOTS 256 // pivot points @@ -214,10 +214,8 @@ typedef struct { char label[32]; // textual name char name[64]; // file name - cache_user_t cache; // cache index pointer -#ifndef __amd64 - int data; // hack for group 0 -#endif + int unused1; // // was "cache" - index pointer + int unused2; // was "data" - hack for group 0 } mstudioseqgroup_t; // sequence descriptions diff --git a/pm_shared/pm_defs.h b/pm_shared/pm_defs.h index d29bff19..cd17ce54 100644 --- a/pm_shared/pm_defs.h +++ b/pm_shared/pm_defs.h @@ -201,7 +201,7 @@ typedef struct playermove_s pmtrace_t (*PM_PlayerTrace)( float *start, float *end, int traceFlags, int ignore_pe ); #endif struct pmtrace_s *(*PM_TraceLine)( float *start, float *end, int flags, int usehulll, int ignore_pe ); - long (*RandomLong)( long lLow, long lHigh ); + int (*RandomLong)( int lLow, int lHigh ); float (*RandomFloat)( float flLow, float flHigh ); int (*PM_GetModelType)( struct model_s *mod ); void (*PM_GetModelBounds)( struct model_s *mod, float *mins, float *maxs ); diff --git a/pm_shared/pm_materials.h b/pm_shared/pm_materials.h index cd1051d2..e625b4fc 100644 --- a/pm_shared/pm_materials.h +++ b/pm_shared/pm_materials.h @@ -28,4 +28,5 @@ #define CHAR_TEX_COMPUTER 'P' #define CHAR_TEX_GLASS 'Y' #define CHAR_TEX_FLESH 'F' +#define CHAR_TEX_SNOW 'N' #endif//PM_MATERIALS_H diff --git a/pm_shared/pm_shared.c b/pm_shared/pm_shared.c index de855a50..7a1fb966 100644 --- a/pm_shared/pm_shared.c +++ b/pm_shared/pm_shared.c @@ -87,6 +87,8 @@ playermove_t *pmove = NULL; #define PLAYER_LONGJUMP_SPEED 350 // how fast we longjump +#define PLAYER_DUCKING_MULTIPLIER 0.333 + // double to float warning #pragma warning(disable : 4244) #define max(a, b) (((a) > (b)) ? (a) : (b)) @@ -2017,9 +2019,9 @@ void PM_Duck( void ) if( pmove->flags & FL_DUCKING ) { - pmove->cmd.forwardmove *= 0.333; - pmove->cmd.sidemove *= 0.333; - pmove->cmd.upmove *= 0.333; + pmove->cmd.forwardmove *= PLAYER_DUCKING_MULTIPLIER; + pmove->cmd.sidemove *= PLAYER_DUCKING_MULTIPLIER; + pmove->cmd.upmove *= PLAYER_DUCKING_MULTIPLIER; } if( ( pmove->cmd.buttons & IN_DUCK ) || ( pmove->bInDuck ) || ( pmove->flags & FL_DUCKING ) ) @@ -2110,16 +2112,24 @@ void PM_LadderMove( physent_t *pLadder ) { float forward = 0, right = 0; vec3_t vpn, v_right; + float flSpeed = MAX_CLIMB_SPEED; + + // they shouldn't be able to move faster than their maxspeed + if( flSpeed > pmove->maxspeed ) + flSpeed = pmove->maxspeed; AngleVectors( pmove->angles, vpn, v_right, NULL ); + + if( pmove->flags & FL_DUCKING ) + flSpeed *= PLAYER_DUCKING_MULTIPLIER; if( pmove->cmd.buttons & IN_BACK ) - forward -= MAX_CLIMB_SPEED; + forward -= flSpeed; if( pmove->cmd.buttons & IN_FORWARD ) - forward += MAX_CLIMB_SPEED; + forward += flSpeed; if( pmove->cmd.buttons & IN_MOVELEFT ) - right -= MAX_CLIMB_SPEED; + right -= flSpeed; if( pmove->cmd.buttons & IN_MOVERIGHT ) - right += MAX_CLIMB_SPEED; + right += flSpeed; if( pmove->cmd.buttons & IN_JUMP ) { From ecaba0de22483417add665dfbd47271ed058ff10 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 26 Jun 2017 07:06:27 +0500 Subject: [PATCH 008/211] Upload missing file. Fix build. --- cl_dll/com_weapons.cpp | 2 +- cl_dll/com_weapons.h | 2 +- cl_dll/hl/hl_baseentity.cpp | 1 + cl_dll/hl/hl_weapons.cpp | 21 --- dlls/Android.mk | 1 + dlls/CMakeLists.txt | 1 + dlls/Makefile | 1 + dlls/observer.cpp | 268 ++++++++++++++++++++++++++++++++++++ engine/cdll_int.h | 4 +- engine/menu_int.h | 4 +- 10 files changed, 278 insertions(+), 27 deletions(-) create mode 100644 dlls/observer.cpp diff --git a/cl_dll/com_weapons.cpp b/cl_dll/com_weapons.cpp index 4f539df9..cc693b88 100644 --- a/cl_dll/com_weapons.cpp +++ b/cl_dll/com_weapons.cpp @@ -283,7 +283,7 @@ unsigned short stub_PrecacheEvent( int type, const char *s ) return 0; } -const char *stub_NameForFunction( unsigned long function ) +const char *stub_NameForFunction( unsigned int function ) { return "func"; } diff --git a/cl_dll/com_weapons.h b/cl_dll/com_weapons.h index 7e1fdd77..4dd75203 100644 --- a/cl_dll/com_weapons.h +++ b/cl_dll/com_weapons.h @@ -34,7 +34,7 @@ void HUD_SetMaxSpeed( const struct edict_s *ed, float speed ); int stub_PrecacheModel( char* s ); int stub_PrecacheSound( char* s ); unsigned short stub_PrecacheEvent( int type, const char *s ); -const char *stub_NameForFunction( unsigned long function ); +const char *stub_NameForFunction( unsigned int function ); void stub_SetModel( struct edict_s *e, const char *m ); extern cvar_t *cl_lw; diff --git a/cl_dll/hl/hl_baseentity.cpp b/cl_dll/hl/hl_baseentity.cpp index 9a47110f..fc306838 100644 --- a/cl_dll/hl/hl_baseentity.cpp +++ b/cl_dll/hl/hl_baseentity.cpp @@ -314,6 +314,7 @@ int CBasePlayerItem::Restore( class CRestore & ) { return 1; } int CBasePlayerItem::Save( class CSave & ) { return 1; } int CBasePlayerWeapon::Restore( class CRestore & ) { return 1; } int CBasePlayerWeapon::Save( class CSave & ) { return 1; } +float CBasePlayerWeapon::GetNextAttackDelay( float flTime ) { return flTime; } void CBasePlayerItem::SetObjectCollisionBox( void ) { } void CBasePlayerItem::FallInit( void ) { } void CBasePlayerItem::FallThink( void ) { } diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 6d555b4c..8c6909e3 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -560,27 +560,6 @@ void UTIL_ParticleLine( CBasePlayer *player, float *start, float *end, float lif gEngfuncs.pEfxAPI->R_ParticleLine( start, end, r, g, b, life ); } -/* -===================== -CBasePlayerWeapon::PrintState - -For debugging, print out state variables to log file -===================== -*/ -void CBasePlayerWeapon::PrintState( void ) -{ - COM_Log( "c:\\hl.log", "%.4f ", gpGlobals->time ); - COM_Log( "c:\\hl.log", "%.4f ", m_pPlayer->m_flNextAttack ); - COM_Log( "c:\\hl.log", "%.4f ", m_flNextPrimaryAttack ); - COM_Log( "c:\\hl.log", "%.4f ", m_flTimeWeaponIdle - gpGlobals->time ); - COM_Log( "c:\\hl.log", "%i ", m_iClip ); -} - -int RandomLong( int a, int b ) -{ - return gEngfuncs.pfnRandomLong( a, b ); -} - /* ===================== HUD_InitClientWeapons diff --git a/dlls/Android.mk b/dlls/Android.mk index 7fcdf581..b160c424 100644 --- a/dlls/Android.mk +++ b/dlls/Android.mk @@ -90,6 +90,7 @@ LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \ multiplay_gamerules.cpp \ nihilanth.cpp \ nodes.cpp \ + observer.cpp \ osprey.cpp \ pathcorner.cpp \ plane.cpp \ diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index cc0063b4..e0b6a8b3 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -92,6 +92,7 @@ set (SVDLL_SOURCES multiplay_gamerules.cpp nihilanth.cpp nodes.cpp + observer.cpp osprey.cpp pathcorner.cpp plane.cpp diff --git a/dlls/Makefile b/dlls/Makefile index c75731d5..9c3a84f2 100644 --- a/dlls/Makefile +++ b/dlls/Makefile @@ -129,6 +129,7 @@ OBJ = \ $(DLL_OBJDIR)/multiplay_gamerules.o \ $(DLL_OBJDIR)/nihilanth.o \ $(DLL_OBJDIR)/nodes.o \ + $(DLL_OBJDIR)/observer.cpp \^M $(DLL_OBJDIR)/osprey.o \ $(DLL_OBJDIR)/pathcorner.o \ $(DLL_OBJDIR)/plane.o \ diff --git a/dlls/observer.cpp b/dlls/observer.cpp new file mode 100644 index 00000000..0eda7490 --- /dev/null +++ b/dlls/observer.cpp @@ -0,0 +1,268 @@ +//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// Purpose: Functionality for the observer chase camera +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//============================================================================= +#include "extdll.h" +#include "util.h" +#include "cbase.h" +#include "player.h" +#include "weapons.h" +#include "pm_shared.h" + +extern int gmsgCurWeapon; +extern int gmsgSetFOV; +// Find the next client in the game for this player to spectate +void CBasePlayer::Observer_FindNextPlayer( bool bReverse ) +{ + // MOD AUTHORS: Modify the logic of this function if you want to restrict the observer to watching + // only a subset of the players. e.g. Make it check the target's team. + int iStart; + if( m_hObserverTarget ) + iStart = ENTINDEX( m_hObserverTarget->edict() ); + else + iStart = ENTINDEX( edict() ); + int iCurrent = iStart; + m_hObserverTarget = NULL; + int iDir = bReverse ? -1 : 1; + + do + { + iCurrent += iDir; + + // Loop through the clients + if( iCurrent > gpGlobals->maxClients ) + iCurrent = 1; + if( iCurrent < 1 ) + iCurrent = gpGlobals->maxClients; + + CBaseEntity *pEnt = UTIL_PlayerByIndex( iCurrent ); + if( !pEnt ) + continue; + if( pEnt == this ) + continue; + // Don't spec observers or players who haven't picked a class yet + if( ( (CBasePlayer*)pEnt )->IsObserver() || ( pEnt->pev->effects & EF_NODRAW ) ) + continue; + + // MOD AUTHORS: Add checks on target here. + m_hObserverTarget = pEnt; + break; + }while( iCurrent != iStart ); + + // Did we find a target? + if( m_hObserverTarget ) + { + // Move to the target + UTIL_SetOrigin( pev, m_hObserverTarget->pev->origin ); + + // ALERT( at_console, "Now Tracking %s\n", STRING( m_hObserverTarget->pev->netname ) ); + + // Store the target in pev so the physics DLL can get to it + if( pev->iuser1 != OBS_ROAMING ) + pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); + } +} + +// Handle buttons in observer mode +void CBasePlayer::Observer_HandleButtons() +{ + // Slow down mouse clicks + if( m_flNextObserverInput > gpGlobals->time ) + return; + + // Jump changes from modes: Chase to Roaming + if( m_afButtonPressed & IN_JUMP ) + { + if( pev->iuser1 == OBS_CHASE_LOCKED ) + Observer_SetMode( OBS_CHASE_FREE ); + else if( pev->iuser1 == OBS_CHASE_FREE ) + Observer_SetMode( OBS_IN_EYE ); + else if( pev->iuser1 == OBS_IN_EYE ) + Observer_SetMode( OBS_ROAMING ); + else if( pev->iuser1 == OBS_ROAMING ) + Observer_SetMode( OBS_MAP_FREE ); + else if( pev->iuser1 == OBS_MAP_FREE ) + Observer_SetMode( OBS_MAP_CHASE ); + else + Observer_SetMode( OBS_CHASE_FREE ); // don't use OBS_CHASE_LOCKED anymore + + m_flNextObserverInput = gpGlobals->time + 0.2; + } + + // Attack moves to the next player + if ( m_afButtonPressed & IN_ATTACK )//&& pev->iuser1 != OBS_ROAMING ) + { + Observer_FindNextPlayer( false ); + + m_flNextObserverInput = gpGlobals->time + 0.2; + } + + // Attack2 moves to the prev player + if ( m_afButtonPressed & IN_ATTACK2)// && pev->iuser1 != OBS_ROAMING ) + { + Observer_FindNextPlayer( true ); + + m_flNextObserverInput = gpGlobals->time + 0.2; + } +} + +void CBasePlayer::Observer_CheckTarget() +{ + if( pev->iuser1 == OBS_ROAMING ) + return; + + // try to find a traget if we have no current one + if( m_hObserverTarget == NULL ) + { + Observer_FindNextPlayer( false ); + + if( m_hObserverTarget == NULL ) + { + // no target found at all + + int lastMode = pev->iuser1; + + Observer_SetMode( OBS_ROAMING ); + + m_iObserverLastMode = lastMode; // don't overwrite users lastmode + + return; // we still have np target return + } + } + + CBasePlayer* target = (CBasePlayer*)( UTIL_PlayerByIndex( ENTINDEX( m_hObserverTarget->edict() ) ) ); + + if( !target ) + { + Observer_FindNextPlayer( false ); + return; + } + + // check taget + if( target->pev->deadflag == DEAD_DEAD ) + { + if( ( target->m_fDeadTime + 2.0f ) < gpGlobals->time ) + { + // 3 secs after death change target + Observer_FindNextPlayer( false ); + return; + } + } +} + +void CBasePlayer::Observer_CheckProperties() +{ + // try to find a traget if we have no current one + if( pev->iuser1 == OBS_IN_EYE && m_hObserverTarget != NULL ) + { + CBasePlayer* target = (CBasePlayer*)( UTIL_PlayerByIndex( ENTINDEX( m_hObserverTarget->edict() ) ) ); + + if( !target ) + return; + + int weapon = ( target->m_pActiveItem != NULL ) ? target->m_pActiveItem->m_iId : 0; + // use fov of tracked client + if( m_iFOV != target->m_iFOV || m_iObserverWeapon != weapon ) + { + m_iFOV = target->m_iFOV; + m_iClientFOV = m_iFOV; + // write fov before wepon data, so zoomed crosshair is set correctly + MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); + WRITE_BYTE( m_iFOV ); + MESSAGE_END(); + + m_iObserverWeapon = weapon; + //send weapon update + MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); + WRITE_BYTE( 1 ); // 1 = current weapon, not on target + WRITE_BYTE( m_iObserverWeapon ); + WRITE_BYTE( 0 ); // clip + MESSAGE_END(); + } + } + else + { + m_iFOV = 90; + + if( m_iObserverWeapon != 0 ) + { + m_iObserverWeapon = 0; + + MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); + WRITE_BYTE( 1 ); // 1 = current weapon + WRITE_BYTE( m_iObserverWeapon ); + WRITE_BYTE( 0 ); // clip + MESSAGE_END(); + } + } +} + +// Attempt to change the observer mode +void CBasePlayer::Observer_SetMode( int iMode ) +{ + + // Just abort if we're changing to the mode we're already in + if( iMode == pev->iuser1 ) + return; + + // is valid mode ? + if( iMode < OBS_CHASE_LOCKED || iMode > OBS_MAP_CHASE ) + iMode = OBS_IN_EYE; // now it is + // verify observer target again + if( m_hObserverTarget != NULL ) + { + CBaseEntity *pEnt = m_hObserverTarget; + + if( ( pEnt == this ) || ( pEnt == NULL ) ) + m_hObserverTarget = NULL; + else if( ( (CBasePlayer*)pEnt )->IsObserver() || ( pEnt->pev->effects & EF_NODRAW ) ) + m_hObserverTarget = NULL; + } + + // set spectator mode + pev->iuser1 = iMode; + + // if we are not roaming, we need a valid target to track + if( ( iMode != OBS_ROAMING ) && ( m_hObserverTarget == NULL ) ) + { + Observer_FindNextPlayer( false ); + + // if we didn't find a valid target switch to roaming + if( m_hObserverTarget == NULL ) + { + ClientPrint( pev, HUD_PRINTCENTER, "#Spec_NoTarget" ); + pev->iuser1 = OBS_ROAMING; + } + } + + // set target if not roaming + if( pev->iuser1 == OBS_ROAMING ) + { + pev->iuser2 = 0; + } + else + pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); + + pev->iuser3 = 0; // clear second target from death cam + + // print spepctaor mode on client screen + + char modemsg[16]; + sprintf( modemsg,"#Spec_Mode%i", pev->iuser1 ); + ClientPrint( pev, HUD_PRINTCENTER, modemsg ); + + m_iObserverLastMode = iMode; +} diff --git a/engine/cdll_int.h b/engine/cdll_int.h index eaa7f4e8..a0dc59c2 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -211,7 +211,7 @@ typedef struct cl_enginefuncs_s void (*pfnPlaybackEvent)( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); void (*pfnWeaponAnim)( int iAnim, int body ); float (*pfnRandomFloat)( float flLow, float flHigh ); - long (*pfnRandomLong)( long lLow, long lHigh ); + int (*pfnRandomLong)( int lLow, int lHigh ); void (*pfnHookEvent)( char *name, void ( *pfnEvent )( struct event_args_s *args )); int (*Con_IsVisible) (); const char *(*pfnGetGameDirectory)( void ); @@ -311,4 +311,4 @@ typedef struct cl_enginefuncs_s } #endif -#endif//CDLL_INT_H \ No newline at end of file +#endif//CDLL_INT_H diff --git a/engine/menu_int.h b/engine/menu_int.h index 53b0725a..69c10ce4 100644 --- a/engine/menu_int.h +++ b/engine/menu_int.h @@ -155,7 +155,7 @@ typedef struct ui_enginefuncs_s // menu interface is freezed at version 0.75 // new functions starts here float (*pfnRandomFloat)( float flLow, float flHigh ); - long (*pfnRandomLong)( long lLow, long lHigh ); + int (*pfnRandomLong)( int lLow, int lHigh ); void (*pfnSetCursor)( void *hCursor ); // change cursor int (*pfnIsMapValid)( char *filename ); @@ -185,4 +185,4 @@ typedef struct typedef int (*MENUAPI)( UI_FUNCTIONS *pFunctionTable, ui_enginefuncs_t* engfuncs, ui_globalvars_t *pGlobals ); -#endif//MENU_INT_H \ No newline at end of file +#endif//MENU_INT_H From d217780789a2ca207bde3e8f50f7ec142f274b92 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 26 Jun 2017 07:41:01 +0500 Subject: [PATCH 009/211] Try fix build again. --- dlls/client.cpp | 3 ++- dlls/util.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dlls/client.cpp b/dlls/client.cpp index 74be0ea3..72538b02 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -38,6 +38,7 @@ #include "weaponinfo.h" #include "usercmd.h" #include "netadr.h" +#include "pm_shared.h" extern DLL_GLOBAL ULONG g_ulModelIndexPlayer; extern DLL_GLOBAL BOOL g_fGameOver; @@ -550,7 +551,7 @@ void ClientCommand( edict_t *pEntity ) { GetClassPtr( (CBasePlayer *)pev )->SelectLastItem(); } - else if( FStrEq( pcmd, "spectate" ) // clients wants to become a spectator + else if( FStrEq( pcmd, "spectate" ) ) // clients wants to become a spectator { // always allow proxies to become a spectator if( ( pev->flags & FL_PROXY ) || allow_spectators.value ) diff --git a/dlls/util.cpp b/dlls/util.cpp index 4fc0d51a..9c7d9803 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1890,7 +1890,7 @@ void CSave::WriteFunction( const char *pname, void **data, int count ) { const char *functionName; - functionName = NAME_FOR_FUNCTION( *data ); + functionName = NAME_FOR_FUNCTION( (unsigned int)(size_t)*data ); if( functionName ) BufferField( pname, strlen( functionName ) + 1, functionName ); else From 2faa732aa1d3fa90937c0aac01e82cb836e2f34c Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 29 Jun 2017 18:56:03 +0500 Subject: [PATCH 010/211] Apply some @AlliedModders's patches. --- cl_dll/ammo.cpp | 4 +-- cl_dll/com_weapons.cpp | 8 ++--- cl_dll/com_weapons.h | 8 ++--- cl_dll/death.cpp | 17 +++++----- cl_dll/entity.cpp | 16 ++++----- cl_dll/ev_hldm.cpp | 30 ++++++++-------- cl_dll/geiger.cpp | 56 +++++++++++++++--------------- cl_dll/hl/hl_baseentity.cpp | 12 +++---- cl_dll/hl/hl_weapons.cpp | 8 ++--- cl_dll/hud.h | 12 +++---- cl_dll/hud_redraw.cpp | 10 +++--- cl_dll/message.cpp | 6 ++-- cl_dll/status_icons.cpp | 4 +-- cl_dll/text_message.cpp | 20 +++++------ cl_dll/view.cpp | 8 ++--- common/cvardef.h | 4 +-- dlls/activity.h | 2 +- dlls/activitymap.h | 2 +- dlls/aflock.cpp | 1 - dlls/agrunt.cpp | 6 ++-- dlls/animation.cpp | 6 ++-- dlls/apache.cpp | 5 ++- dlls/barnacle.cpp | 6 ++-- dlls/barney.cpp | 16 ++++----- dlls/basemonster.h | 4 +-- dlls/bigmomma.cpp | 7 ++-- dlls/bmodels.cpp | 4 +-- dlls/bullsquid.cpp | 12 +++---- dlls/buttons.cpp | 20 +++++------ dlls/cbase.cpp | 4 +-- dlls/cbase.h | 7 ++-- dlls/client.cpp | 26 ++++++-------- dlls/combat.cpp | 19 ++++++----- dlls/controller.cpp | 9 +++-- dlls/crossbow.cpp | 3 +- dlls/crowbar.cpp | 4 +-- dlls/decals.h | 2 +- dlls/doors.cpp | 24 ++++++------- dlls/effects.cpp | 18 +++++----- dlls/effects.h | 8 ++--- dlls/egon.cpp | 10 +++--- dlls/enginecallback.h | 8 +++++ dlls/extdll.h | 6 ++++ dlls/func_break.cpp | 13 ++++--- dlls/func_tank.cpp | 24 ++++++------- dlls/gargantua.cpp | 3 +- dlls/gauss.cpp | 9 +++-- dlls/genericmonster.cpp | 2 +- dlls/ggrenade.cpp | 14 ++++---- dlls/gman.cpp | 8 ++--- dlls/h_battery.cpp | 6 ++-- dlls/h_cine.cpp | 4 +-- dlls/h_cycler.cpp | 6 ++-- dlls/hassassin.cpp | 6 ++-- dlls/headcrab.cpp | 4 +-- dlls/healthkit.cpp | 6 ++-- dlls/hgrunt.cpp | 26 +++++++------- dlls/hornet.cpp | 6 ++-- dlls/houndeye.cpp | 2 +- dlls/ichthyosaur.cpp | 8 ++--- dlls/islave.cpp | 20 +++++------ dlls/leech.cpp | 2 +- dlls/lights.cpp | 17 +++++----- dlls/maprules.cpp | 14 ++++---- dlls/monsters.cpp | 22 ++++++------ dlls/monsterstate.cpp | 6 ++-- dlls/mpstubb.cpp | 4 +-- dlls/multiplay_gamerules.cpp | 16 ++++----- dlls/nihilanth.cpp | 44 ++++++++++++------------ dlls/nodes.cpp | 19 +++++++---- dlls/nodes.h | 4 ++- dlls/observer.cpp | 18 +++++----- dlls/osprey.cpp | 8 ++--- dlls/plats.cpp | 8 ++--- dlls/player.cpp | 66 ++++++++++++++++++------------------ dlls/player.h | 4 +-- dlls/satchel.cpp | 4 +-- dlls/saverestore.h | 11 ++++-- dlls/schedule.cpp | 22 ++++++------ dlls/scientist.cpp | 18 +++++----- dlls/scripted.cpp | 4 +-- dlls/skill.cpp | 5 ++- dlls/skill.h | 2 +- dlls/sound.cpp | 12 +++---- dlls/squadmonster.cpp | 12 +++---- dlls/squadmonster.h | 2 +- dlls/squeakgrenade.cpp | 18 +++++----- dlls/talkmonster.cpp | 32 ++++++++--------- dlls/talkmonster.h | 4 +-- dlls/teamplay_gamerules.cpp | 10 +++--- dlls/tentacle.cpp | 9 ++--- dlls/triggers.cpp | 10 +++--- dlls/tripmine.cpp | 8 ++--- dlls/turret.cpp | 18 +++++----- dlls/util.cpp | 20 +++++------ dlls/util.h | 9 ++--- dlls/vector.h | 14 ++++---- dlls/weapons.cpp | 4 +-- dlls/weapons.h | 8 +++-- dlls/world.cpp | 4 +-- dlls/xen.cpp | 6 ++-- dlls/zombie.cpp | 2 +- engine/custom.h | 6 ++++ engine/edict.h | 8 ++++- engine/eiface.h | 50 ++++++++++++++------------- engine/progdefs.h | 8 ++++- pm_shared/pm_debug.c | 2 ++ pm_shared/pm_debug.h | 6 ++++ pm_shared/pm_defs.h | 6 ++++ pm_shared/pm_info.h | 6 ++++ pm_shared/pm_math.c | 2 ++ pm_shared/pm_shared.c | 26 +++++++++----- pm_shared/pm_shared.h | 6 ++++ 113 files changed, 671 insertions(+), 604 deletions(-) diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index 988bd6fa..860cde42 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -877,11 +877,11 @@ int CHudAmmo::Draw( float flTime ) x = ScreenWidth - ( 8 * AmmoWidth ) - iIconWidth; x = gHUD.DrawHudNumber( x, y, iFlags | DHN_3DIGITS, pw->iClip, r, g, b ); - wrect_t rc; + /*wrect_t rc; rc.top = 0; rc.left = 0; rc.right = AmmoWidth; - rc.bottom = 100; + rc.bottom = 100;*/ int iBarWidth = AmmoWidth / 10; diff --git a/cl_dll/com_weapons.cpp b/cl_dll/com_weapons.cpp index cc693b88..e50de419 100644 --- a/cl_dll/com_weapons.cpp +++ b/cl_dll/com_weapons.cpp @@ -41,7 +41,7 @@ COM_Log Log debug messages to file ( appends ) ==================== */ -void COM_Log( char *pszFile, char *fmt, ... ) +void COM_Log( const char *pszFile, const char *fmt, ... ) { va_list argptr; char string[1024]; @@ -111,7 +111,7 @@ HUD_PlaySound Play a sound, if we are seeing this command for the first time ===================== */ -void HUD_PlaySound( char *sound, float volume ) +void HUD_PlaySound( const char *sound, float volume ) { if( !g_runfuncs || !g_finalstate ) return; @@ -268,12 +268,12 @@ stub functions for such things as precaching. So we don't have to modify weapon is compiled into both game and client .dlls. ====================== */ -int stub_PrecacheModel( char* s ) +int stub_PrecacheModel( const char* s ) { return 0; } -int stub_PrecacheSound( char* s ) +int stub_PrecacheSound( const char* s ) { return 0; } diff --git a/cl_dll/com_weapons.h b/cl_dll/com_weapons.h index 4dd75203..8559e20b 100644 --- a/cl_dll/com_weapons.h +++ b/cl_dll/com_weapons.h @@ -20,7 +20,7 @@ extern "C" void _DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); } -void COM_Log( char *pszFile, char *fmt, ... ); +void COM_Log( const char *pszFile, const char *fmt, ... ); int CL_IsDead( void ); float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ); @@ -28,11 +28,11 @@ int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); int HUD_GetWeaponAnim( void ); void HUD_SendWeaponAnim( int iAnim, int body, int force ); -void HUD_PlaySound( char *sound, float volume ); +void HUD_PlaySound( const char *sound, float volume ); void HUD_PlaybackEvent( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); void HUD_SetMaxSpeed( const struct edict_s *ed, float speed ); -int stub_PrecacheModel( char* s ); -int stub_PrecacheSound( char* s ); +int stub_PrecacheModel( const char* s ); +int stub_PrecacheSound( const char* s ); unsigned short stub_PrecacheEvent( int type, const char *s ); const char *stub_NameForFunction( unsigned int function ); void stub_SetModel( struct edict_s *e, const char *m ); diff --git a/cl_dll/death.cpp b/cl_dll/death.cpp index 455dfd36..579fc255 100644 --- a/cl_dll/death.cpp +++ b/cl_dll/death.cpp @@ -187,7 +187,8 @@ int CHudDeathNotice::MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbu gHUD.m_Scoreboard.GetAllPlayersInfo(); // Get the Killer's name - char *killer_name = g_PlayerInfoList[killer].name; + const char *killer_name = ""; + killer_name = g_PlayerInfoList[killer].name; if( !killer_name ) { killer_name = ""; @@ -201,11 +202,11 @@ int CHudDeathNotice::MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbu } // Get the Victim's name - char *victim_name = NULL; + const char *victim_name = ""; // If victim is -1, the killer killed a specific, non-player object (like a sentrygun) - if ( ( (char)victim ) != -1 ) + if( ( (char)victim ) != -1 ) victim_name = g_PlayerInfoList[victim].name; - if ( !victim_name ) + if( !victim_name ) { victim_name = ""; rgDeathNoticeList[i].szVictim[0] = 0; @@ -218,7 +219,7 @@ int CHudDeathNotice::MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbu } // Is it a non-player object kill? - if ( ( (char)victim ) == -1 ) + if( ( (char)victim ) == -1 ) { rgDeathNoticeList[i].iNonPlayerKill = TRUE; @@ -227,10 +228,10 @@ int CHudDeathNotice::MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbu } else { - if ( killer == victim || killer == 0 ) + if( killer == victim || killer == 0 ) rgDeathNoticeList[i].iSuicide = TRUE; - if ( !strcmp( killedwith, "d_teammate" ) ) + if( !strcmp( killedwith, "d_teammate" ) ) rgDeathNoticeList[i].iTeamKill = TRUE; } @@ -285,7 +286,7 @@ int CHudDeathNotice::MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbu // replace the code names with the 'real' names if( !strcmp( killedwith + 2, "egon" ) ) strcpy( killedwith, "d_gluon gun" ); - if ( !strcmp( killedwith + 2, "gauss" ) ) + if( !strcmp( killedwith + 2, "gauss" ) ) strcpy( killedwith, "d_tau cannon" ); ConsolePrint( killedwith + 2 ); // skip over the "d_" part diff --git a/cl_dll/entity.cpp b/cl_dll/entity.cpp index 07bd0ff3..303a9d25 100644 --- a/cl_dll/entity.cpp +++ b/cl_dll/entity.cpp @@ -585,10 +585,10 @@ void DLLEXPORT HUD_TempEntUpdate ( static int gTempEntFrame = 0; int i; TEMPENTITY *pTemp, *pnext, *pprev; - float freq, gravity, gravitySlow, life, fastFreq; + float /*freq,*/ gravity, gravitySlow, life, fastFreq; // Nothing to simulate - if ( !*ppTempEntActive ) + if( !*ppTempEntActive ) return; // in order to have tents collide with players, we have to run the player prediction code so @@ -601,7 +601,7 @@ void DLLEXPORT HUD_TempEntUpdate ( gEngfuncs.pEventAPI->EV_PushPMStates(); // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers( -1 ); + gEngfuncs.pEventAPI->EV_SetSolidPlayers( -1 ); // !!!BUGBUG -- This needs to be time based gTempEntFrame = ( gTempEntFrame + 1 ) & 31; @@ -623,7 +623,7 @@ void DLLEXPORT HUD_TempEntUpdate ( } pprev = NULL; - freq = client_time * 0.01; + //freq = client_time * 0.01; fastFreq = client_time * 5.5; gravity = -frametime * cl_gravity; gravitySlow = gravity * 0.5; @@ -709,12 +709,12 @@ void DLLEXPORT HUD_TempEntUpdate ( } else if( pTemp->flags & FTENT_SPIRAL ) { - float s, c; + /*float s, c; s = sin( pTemp->entity.baseline.origin[2] + fastFreq ); - c = cos( pTemp->entity.baseline.origin[2] + fastFreq ); + c = cos( pTemp->entity.baseline.origin[2] + fastFreq );*/ - pTemp->entity.origin[0] += pTemp->entity.baseline.origin[0] * frametime + 8 * sin( client_time * 20 + (int)(size_t)pTemp ); - pTemp->entity.origin[1] += pTemp->entity.baseline.origin[1] * frametime + 4 * sin( client_time * 30 + (int)(size_t)pTemp ); + pTemp->entity.origin[0] += pTemp->entity.baseline.origin[0] * frametime + 8 * sin( client_time * 20 + (size_t)pTemp ); + pTemp->entity.origin[1] += pTemp->entity.baseline.origin[1] * frametime + 4 * sin( client_time * 30 + (size_t)pTemp ); pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; } else diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 9787a839..787e1be8 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -94,7 +94,7 @@ float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *v char chTextureType = CHAR_TEX_CONCRETE; float fvol; float fvolbar; - char *rgsz[4]; + const char *rgsz[4]; int cnt; float fattn = ATTN_NORM; int entity; @@ -568,7 +568,7 @@ void EV_FireShotGunDouble( event_args_t *args ) vec3_t vecSrc, vecAiming; vec3_t vecSpread; vec3_t up, right, forward; - float flSpread = 0.01; + //float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); @@ -622,7 +622,7 @@ void EV_FireShotGunSingle( event_args_t *args ) vec3_t vecSrc, vecAiming; vec3_t vecSpread; vec3_t up, right, forward; - float flSpread = 0.01; + //float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); @@ -679,7 +679,7 @@ void EV_FireMP5( event_args_t *args ) int shell; vec3_t vecSrc, vecAiming; vec3_t up, right, forward; - float flSpread = 0.01; + //float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); @@ -769,7 +769,7 @@ void EV_FirePython( event_args_t *args ) vec3_t vecSrc, vecAiming; vec3_t up, right, forward; - float flSpread = 0.01; + //float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); @@ -860,16 +860,16 @@ void EV_FireGauss( event_args_t *args ) vec3_t angles; vec3_t velocity; float flDamage = args->fparam1; - int primaryfire = args->bparam1; + //int primaryfire = args->bparam1; int m_fPrimaryFire = args->bparam1; - int m_iWeaponVolume = GAUSS_PRIMARY_FIRE_VOLUME; + //int m_iWeaponVolume = GAUSS_PRIMARY_FIRE_VOLUME; vec3_t vecSrc; vec3_t vecDest; - edict_t *pentIgnore; + //edict_t *pentIgnore; pmtrace_t tr, beam_tr; float flMaxFrac = 1.0; - int nTotal = 0; + //int nTotal = 0; int fHasPunched = 0; int fFirstBeam = 1; int nMaxHits = 10; @@ -980,7 +980,7 @@ void EV_FireGauss( event_args_t *args ) { float n; - pentIgnore = NULL; + //pentIgnore = NULL; n = -DotProduct( tr.plane.normal, forward ); @@ -1412,12 +1412,12 @@ BEAM *pBeam2; void EV_EgonFire( event_args_t *args ) { - int idx, iFireState, iFireMode; + int idx, /*iFireState,*/ iFireMode; vec3_t origin; idx = args->entindex; VectorCopy( args->origin, origin ); - iFireState = args->iparam1; + //iFireState = args->iparam1; iFireMode = args->iparam2; int iStartup = args->bparam1; @@ -1539,13 +1539,13 @@ enum hgun_e void EV_HornetGunFire( event_args_t *args ) { - int idx, iFireMode; + int idx; //, iFireMode; vec3_t origin, angles, vecSrc, forward, right, up; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); - iFireMode = args->iparam1; + //iFireMode = args->iparam1; //Only play the weapon anims if I shot it. if( EV_IsLocal( idx ) ) @@ -1554,7 +1554,7 @@ void EV_HornetGunFire( event_args_t *args ) gEngfuncs.pEventAPI->EV_WeaponAnimation( HGUN_SHOOT, 1 ); } - switch( gEngfuncs.pfnRandomLong( 0 , 2 ) ) + switch( gEngfuncs.pfnRandomLong( 0, 2 ) ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "agrunt/ag_fire1.wav", 1, ATTN_NORM, 0, 100 ); diff --git a/cl_dll/geiger.cpp b/cl_dll/geiger.cpp index 7ccaf1d3..097889b9 100644 --- a/cl_dll/geiger.cpp +++ b/cl_dll/geiger.cpp @@ -65,7 +65,7 @@ int CHudGeiger::Draw( float flTime ) { int pct; float flvol = 0.0f; - int rg[3]; + //int rg[3]; int i; if( m_iGeigerRange < 1000 && m_iGeigerRange > 0 ) @@ -79,61 +79,61 @@ int CHudGeiger::Draw( float flTime ) { pct = 2; flvol = 0.4; //Con_Printf( "range > 600\n" ); - rg[0] = 1; - rg[1] = 1; + //rg[0] = 1; + //rg[1] = 1; i = 2; } else if( m_iGeigerRange > 500 ) { pct = 4; flvol = 0.5; //Con_Printf( "range > 500\n" ); - rg[0] = 1; - rg[1] = 2; + //rg[0] = 1; + //rg[1] = 2; i = 2; } else if( m_iGeigerRange > 400 ) { pct = 8; flvol = 0.6; //Con_Printf( "range > 400\n" ); - rg[0] = 1; - rg[1] = 2; - rg[2] = 3; + //rg[0] = 1; + //rg[1] = 2; + //rg[2] = 3; i = 3; } else if( m_iGeigerRange > 300 ) { pct = 8; flvol = 0.7; //Con_Printf( "range > 300\n" ); - rg[0] = 2; - rg[1] = 3; - rg[2] = 4; + //rg[0] = 2; + //rg[1] = 3; + //rg[2] = 4; i = 3; } else if( m_iGeigerRange > 200 ) { pct = 28; flvol = 0.78; //Con_Printf( "range > 200\n" ); - rg[0] = 2; - rg[1] = 3; - rg[2] = 4; + //rg[0] = 2; + //rg[1] = 3; + //rg[2] = 4; i = 3; } else if( m_iGeigerRange > 150 ) { pct = 40; flvol = 0.80; //Con_Printf( "range > 150\n" ); - rg[0] = 3; - rg[1] = 4; - rg[2] = 5; + //rg[0] = 3; + //rg[1] = 4; + //rg[2] = 5; i = 3; } else if( m_iGeigerRange > 100 ) { pct = 60; flvol = 0.85; //Con_Printf( "range > 100\n" ); - rg[0] = 3; - rg[1] = 4; - rg[2] = 5; + //rg[0] = 3; + //rg[1] = 4; + //rg[2] = 5; i = 3; } else if( m_iGeigerRange > 75 ) @@ -141,29 +141,29 @@ int CHudGeiger::Draw( float flTime ) pct = 80; flvol = 0.9; //Con_Printf( "range > 75\n" ); //gflGeigerDelay = cl.time + GEIGERDELAY * 0.75; - rg[0] = 4; - rg[1] = 5; - rg[2] = 6; + //rg[0] = 4; + //rg[1] = 5; + //rg[2] = 6; i = 3; } else if( m_iGeigerRange > 50 ) { pct = 90; flvol = 0.95; //Con_Printf( "range > 50\n" ); - rg[0] = 5; - rg[1] = 6; + //rg[0] = 5; + //rg[1] = 6; i = 2; } else { pct = 95; flvol = 1.0; //Con_Printf( "range < 50\n" ); - rg[0] = 5; - rg[1] = 6; + //rg[0] = 5; + //rg[1] = 6; i = 2; } - flvol = ( flvol * ( (rand() & 127) ) / 255) + 0.25; // UTIL_RandomFloat(0.25, 0.5); + flvol = ( flvol * ( ( rand() & 127 ) ) / 255 ) + 0.25; // UTIL_RandomFloat( 0.25, 0.5 ); if( ( rand() & 127 ) < pct || ( rand() & 127 ) < pct ) { diff --git a/cl_dll/hl/hl_baseentity.cpp b/cl_dll/hl/hl_baseentity.cpp index fc306838..d24c0ef4 100644 --- a/cl_dll/hl/hl_baseentity.cpp +++ b/cl_dll/hl/hl_baseentity.cpp @@ -54,7 +54,7 @@ int CBaseEntity::IsDormant( void ) { return 0; } BOOL CBaseEntity::IsInWorld( void ) { return TRUE; } int CBaseEntity::ShouldToggle( USE_TYPE useType, BOOL currentState ) { return 0; } int CBaseEntity::DamageDecal( int bitsDamageType ) { return -1; } -CBaseEntity *CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) { return NULL; } +CBaseEntity *CBaseEntity::Create( const char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) { return NULL; } void CBaseEntity::SUB_Remove( void ) { } // CBaseDelay Stubs @@ -146,7 +146,7 @@ int CBaseMonster::CheckEnemy( CBaseEntity *pEnemy ) { return 0; } void CBaseMonster::PushEnemy( CBaseEntity *pEnemy, Vector &vecLastKnownPos ) { } BOOL CBaseMonster::PopEnemy() { return FALSE; } void CBaseMonster::SetActivity( Activity NewActivity ) { } -void CBaseMonster::SetSequenceByName( char *szSequence ) { } +void CBaseMonster::SetSequenceByName( const char *szSequence ) { } int CBaseMonster::CheckLocalMove( const Vector &vecStart, const Vector &vecEnd, CBaseEntity *pTarget, float *pflDist ) { return 0; } float CBaseMonster::OpenDoorAndWait( entvars_t *pevDoor ) { return 0.0; } void CBaseMonster::AdvanceRoute( float distance ) { } @@ -214,7 +214,7 @@ void CBaseMonster::MonsterInitDead( void ) { } BOOL CBaseMonster::BBoxFlat( void ) { return TRUE; } BOOL CBaseMonster::GetEnemy( void ) { return FALSE; } void CBaseMonster::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -CBaseEntity* CBaseMonster::DropItem( char *pszItemName, const Vector &vecPos, const Vector &vecAng ) { return NULL; } +CBaseEntity* CBaseMonster::DropItem( const char *pszItemName, const Vector &vecPos, const Vector &vecAng ) { return NULL; } BOOL CBaseMonster::ShouldFadeOnDeath( void ) { return FALSE; } void CBaseMonster::RadiusDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) { } void CBaseMonster::RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) { } @@ -258,8 +258,8 @@ void CBasePlayer::PreThink(void) { } void CBasePlayer::CheckTimeBasedDamage() { } void CBasePlayer::UpdateGeigerCounter( void ) { } void CBasePlayer::CheckSuitUpdate() { } -void CBasePlayer::SetSuitUpdate(char *name, int fgroup, int iNoRepeatTime) { } -void CBasePlayer::UpdatePlayerSound ( void ) { } +void CBasePlayer::SetSuitUpdate( const char *name, int fgroup, int iNoRepeatTime ) { } +void CBasePlayer::UpdatePlayerSound( void ) { } void CBasePlayer::PostThink() { } void CBasePlayer::Precache( void ) { } int CBasePlayer::Save( CSave &save ) { return 0; } @@ -298,7 +298,7 @@ BOOL CBasePlayer::HasPlayerItem( CBasePlayerItem *pCheckItem ) { return FALSE; } BOOL CBasePlayer::SwitchWeapon( CBasePlayerItem *pWeapon ) { return FALSE; } Vector CBasePlayer::GetGunPosition( void ) { return g_vecZero; } const char *CBasePlayer::TeamID( void ) { return ""; } -int CBasePlayer::GiveAmmo( int iCount, char *szName, int iMax ) { return 0; } +int CBasePlayer::GiveAmmo( int iCount, const char *szName, int iMax ) { return 0; } void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) { } void CBasePlayer::AddPointsToTeam( int score, BOOL bAllowNegativeScore ) { } diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 8c6909e3..8f8baea7 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -75,7 +75,7 @@ AlertMessage Print debug messages to console ====================== */ -void AlertMessage( ALERT_TYPE atype, char *szFmt, ... ) +void AlertMessage( ALERT_TYPE atype, const char *szFmt, ... ) { va_list argptr; static char string[1024]; @@ -96,7 +96,7 @@ bool bIsMultiplayer( void ) } //Just loads a v_ model. -void LoadVModel( char *szViewModel, CBasePlayer *m_pPlayer ) +void LoadVModel( const char *szViewModel, CBasePlayer *m_pPlayer ) { gEngfuncs.CL_LoadModel( szViewModel, &m_pPlayer->pev->viewmodel ); } @@ -208,7 +208,7 @@ CBasePlayerWeapon::DefaultDeploy ===================== */ -BOOL CBasePlayerWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal, int body ) +BOOL CBasePlayerWeapon::DefaultDeploy( const char *szViewModel, const char *szWeaponModel, int iAnim, const char *szAnimExt, int skiplocal, int body ) { if( !CanDeploy() ) return FALSE; @@ -288,7 +288,7 @@ Only produces random numbers to match the server ones. */ Vector CBaseEntity::FireBulletsPlayer ( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker, int shared_rand ) { - float x = 0, y = 0, z; + float x = 0.0f, y = 0.0f, z; for( ULONG iShot = 1; iShot <= cShots; iShot++ ) { diff --git a/cl_dll/hud.h b/cl_dll/hud.h index ec236003..ab179bbb 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -480,7 +480,7 @@ public: int Init( void ); static char *LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size ); static char *BufferedLocaliseTextString( const char *msg ); - char *LookupString( const char *msg_name, int *msg_dest = NULL ); + const char *LookupString( const char *msg_name, int *msg_dest = NULL ); int MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf ); }; @@ -541,8 +541,8 @@ public: //had to make these public so CHud could access them (to enable concussion icon) //could use a friend declaration instead... - void EnableIcon( char *pszIconName, unsigned char red, unsigned char green, unsigned char blue ); - void DisableIcon( char *pszIconName ); + void EnableIcon( const char *pszIconName, unsigned char red, unsigned char green, unsigned char blue ); + void DisableIcon( const char *pszIconName ); private: typedef struct @@ -588,11 +588,11 @@ public: int m_iFontHeight; int DrawHudNumber( int x, int y, int iFlags, int iNumber, int r, int g, int b ); - int DrawHudString( int x, int y, int iMaxX, char *szString, int r, int g, int b ); - int DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b ); + int DrawHudString( int x, int y, int iMaxX, const char *szString, int r, int g, int b ); + int DrawHudStringReverse( int xpos, int ypos, int iMinX, const char *szString, int r, int g, int b ); int DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b ); int GetNumWidth( int iNumber, int iFlags ); - int DrawHudStringLen( char *szIt ); + int DrawHudStringLen( const char *szIt ); void DrawDarkRectangle( int x, int y, int wide, int tall ); private: diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index c30df36d..5182b484 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -199,7 +199,7 @@ const unsigned char colors[8][3] = {240, 180, 24} }; -int CHud::DrawHudString( int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b ) +int CHud::DrawHudString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int g, int b ) { if( hud_textmode->value == 2 ) { @@ -233,9 +233,7 @@ int CHud::DrawHudString( int xpos, int ypos, int iMaxX, char *szIt, int r, int g return xpos; } - - -int DrawUtfString( int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b ) +int DrawUtfString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int g, int b ) { // xash3d: reset unicode state gEngfuncs.pfnVGUI2DrawCharacterAdditive( 0, 0, 0, 0, 0, 0, 0 ); @@ -262,7 +260,7 @@ int DrawUtfString( int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int return xpos; } -int CHud::DrawHudStringLen( char *szIt ) +int CHud::DrawHudStringLen( const char *szIt ) { int l = 0; for( ; *szIt != 0 && *szIt != '\n'; szIt++ ) @@ -280,7 +278,7 @@ int CHud::DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r } // draws a string from right to left (right-aligned) -int CHud::DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b ) +int CHud::DrawHudStringReverse( int xpos, int ypos, int iMinX, const char *szString, int r, int g, int b ) { // find the end of the string for( char *szIt = szString; *szIt != 0; szIt++ ) diff --git a/cl_dll/message.cpp b/cl_dll/message.cpp index 5d52d413..ff8d97bf 100644 --- a/cl_dll/message.cpp +++ b/cl_dll/message.cpp @@ -29,7 +29,7 @@ DECLARE_MESSAGE( m_Message, GameTitle ) // 1 Global client_textmessage_t for custom messages that aren't in the titles.txt client_textmessage_t g_pCustomMessage; -char *g_pCustomName = "Custom"; +const char *g_pCustomName = "Custom"; char g_pCustomText[1024]; int CHudMessage::Init( void ) @@ -260,7 +260,7 @@ void CHudMessage::MessageDrawScan( client_textmessage_t *pMessage, float time ) width = 0; } else - width += gHUD.m_scrinfo.charWidths[*pText]; + width += gHUD.m_scrinfo.charWidths[(unsigned char)*pText]; pText++; length++; } @@ -310,7 +310,7 @@ int CHudMessage::Draw( float fTime ) { int i, drawn; client_textmessage_t *pMessage; - float endTime = 0; + float endTime = 0.0f; drawn = 0; diff --git a/cl_dll/status_icons.cpp b/cl_dll/status_icons.cpp index c960d5ef..4b2d9726 100644 --- a/cl_dll/status_icons.cpp +++ b/cl_dll/status_icons.cpp @@ -104,7 +104,7 @@ int CHudStatusIcons::MsgFunc_StatusIcon( const char *pszName, int iSize, void *p } // add the icon to the icon list, and set it's drawing color -void CHudStatusIcons::EnableIcon( char *pszIconName, unsigned char red, unsigned char green, unsigned char blue ) +void CHudStatusIcons::EnableIcon( const char *pszIconName, unsigned char red, unsigned char green, unsigned char blue ) { int i; @@ -149,7 +149,7 @@ void CHudStatusIcons::EnableIcon( char *pszIconName, unsigned char red, unsigned } } -void CHudStatusIcons::DisableIcon( char *pszIconName ) +void CHudStatusIcons::DisableIcon( const char *pszIconName ) { // find the sprite is in the current list for( int i = 0; i < MAX_ICONSPRITES; i++ ) diff --git a/cl_dll/text_message.cpp b/cl_dll/text_message.cpp index af62a915..13b62577 100644 --- a/cl_dll/text_message.cpp +++ b/cl_dll/text_message.cpp @@ -45,7 +45,7 @@ int CHudTextMessage::Init( void ) char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size ) { char *dst = dst_buffer; - for( char *src = (char*)msg; *src != 0 && buffer_size > 0; buffer_size-- ) + for( char *src = msg; *src != 0 && buffer_size > 0; buffer_size-- ) { if( *src == '#' ) { @@ -91,12 +91,12 @@ char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, in char *CHudTextMessage::BufferedLocaliseTextString( const char *msg ) { static char dst_buffer[1024]; - LocaliseTextString( msg, dst_buffer, 1024 ); + LocaliseTextString( msg, dst_buffer, sizeof(dst_buffer) ); return dst_buffer; } // Simplified version of LocaliseTextString; assumes string is only one word -char *CHudTextMessage::LookupString( const char *msg, int *msg_dest ) +const char *CHudTextMessage::LookupString( const char *msg, int *msg_dest ) { if( !msg ) return ""; @@ -108,7 +108,7 @@ char *CHudTextMessage::LookupString( const char *msg, int *msg_dest ) client_textmessage_t *clmsg = TextMessageGet( msg + 1 ); if( !clmsg || !(clmsg->pMessage) ) - return (char*)msg; // lookup failed, so return the original string + return msg; // lookup failed, so return the original string if( msg_dest ) { @@ -118,12 +118,12 @@ char *CHudTextMessage::LookupString( const char *msg, int *msg_dest ) *msg_dest = -clmsg->effect; } - return (char*)clmsg->pMessage; + return clmsg->pMessage; } else { // nothing special about this message, so just return the same string - return (char*)msg; + return msg; } } @@ -167,16 +167,16 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf msg_text = strcpy( szBuf[0], msg_text ); // keep reading strings and using C format strings for subsituting the strings into the localised text string - char *sstr1 = LookupString( READ_STRING() ); + const char *sstr1 = LookupString( READ_STRING() ); sstr1 = strcpy( szBuf[1], sstr1 ); StripEndNewlineFromString( sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines - char *sstr2 = LookupString( READ_STRING() ); + const char *sstr2 = LookupString( READ_STRING() ); sstr2 = strcpy( szBuf[2], sstr2 ); StripEndNewlineFromString( sstr2 ); - char *sstr3 = LookupString( READ_STRING() ); + const char *sstr3 = LookupString( READ_STRING() ); sstr3 = strcpy( szBuf[3], sstr3 ); StripEndNewlineFromString( sstr3 ); - char *sstr4 = LookupString( READ_STRING() ); + const char *sstr4 = LookupString( READ_STRING() ); sstr4 = strcpy( szBuf[4], sstr4 ); StripEndNewlineFromString( sstr4 ); char *psz = szBuf[5]; diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index b581cc82..dcd2b1af 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -351,11 +351,11 @@ V_CalcIntermissionRefdef */ void V_CalcIntermissionRefdef( struct ref_params_s *pparams ) { - cl_entity_t *ent, *view; + cl_entity_t /**ent,*/ *view; float old; // ent is the player model ( visible when out of body ) - ent = gEngfuncs.GetLocalPlayer(); + //ent = gEngfuncs.GetLocalPlayer(); // view is the weapon model (only visible from inside body ) view = gEngfuncs.GetViewModel(); @@ -1307,7 +1307,7 @@ void V_GetMapChasePosition( int target, float *cl_angles, float *origin, float * int V_FindViewModelByWeaponModel( int weaponindex ) { - static char *modelmap[][2] = + static const char *modelmap[][2] = { { "models/p_crossbow.mdl", "models/v_crossbow.mdl" }, { "models/p_crowbar.mdl", "models/v_crowbar.mdl" }, @@ -1327,7 +1327,7 @@ int V_FindViewModelByWeaponModel( int weaponindex ) { NULL, NULL } }; - struct model_s * weaponModel = IEngineStudio.GetModelByIndex( weaponindex ); + struct model_s *weaponModel = IEngineStudio.GetModelByIndex( weaponindex ); if( weaponModel ) { diff --git a/common/cvardef.h b/common/cvardef.h index c57b97a7..e8a24581 100644 --- a/common/cvardef.h +++ b/common/cvardef.h @@ -28,8 +28,8 @@ typedef struct cvar_s { - char *name; - char *string; + const char *name; + const char *string; int flags; float value; struct cvar_s *next; diff --git a/dlls/activity.h b/dlls/activity.h index 58b2d8cd..5382d70d 100644 --- a/dlls/activity.h +++ b/dlls/activity.h @@ -99,7 +99,7 @@ typedef enum { typedef struct { int type; - char *name; + const char *name; } activity_map_t; extern activity_map_t activity_map[]; diff --git a/dlls/activitymap.h b/dlls/activitymap.h index 92cadae7..5f77c55a 100644 --- a/dlls/activitymap.h +++ b/dlls/activitymap.h @@ -93,5 +93,5 @@ _A( ACT_FLINCH_LEFTARM ), _A( ACT_FLINCH_RIGHTARM ), _A( ACT_FLINCH_LEFTLEG ), _A( ACT_FLINCH_RIGHTLEG ), -0, NULL +{ 0, NULL } }; diff --git a/dlls/aflock.cpp b/dlls/aflock.cpp index 1e317632..19998a9d 100644 --- a/dlls/aflock.cpp +++ b/dlls/aflock.cpp @@ -567,7 +567,6 @@ void CFlockingFlyer::FlockLeaderThink( void ) TraceResult tr; Vector vecDist;// used for general measurements Vector vecDir;// used for general measurements - int cProcessed = 0;// keep track of how many other boids we've processed float flLeftSide; float flRightSide; diff --git a/dlls/agrunt.cpp b/dlls/agrunt.cpp index 97804f68..c6583fb7 100644 --- a/dlls/agrunt.cpp +++ b/dlls/agrunt.cpp @@ -608,7 +608,7 @@ void CAGrunt::Spawn() //========================================================= void CAGrunt::Precache() { - int i; + size_t i; PRECACHE_MODEL( "models/agrunt.mdl" ); @@ -909,7 +909,7 @@ BOOL CAGrunt::FCanCheckAttacks( void ) //========================================================= BOOL CAGrunt::CheckMeleeAttack1( float flDot, float flDist ) { - if( HasConditions( bits_COND_SEE_ENEMY ) && flDist <= AGRUNT_MELEE_DIST && flDot >= 0.6 && m_hEnemy != NULL ) + if( HasConditions( bits_COND_SEE_ENEMY ) && flDist <= AGRUNT_MELEE_DIST && flDot >= 0.6 && m_hEnemy != 0 ) { return TRUE; } @@ -1160,7 +1160,7 @@ Schedule_t *CAGrunt::GetScheduleOfType( int Type ) case SCHED_FAIL: // no fail schedule specified, so pick a good generic one. { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { // I have an enemy // !!!LATER - what if this enemy is really far away and i'm chasing him? diff --git a/dlls/animation.cpp b/dlls/animation.cpp index 86cb78ae..5454f0e8 100644 --- a/dlls/animation.cpp +++ b/dlls/animation.cpp @@ -268,8 +268,6 @@ int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEve if( !pstudiohdr || pev->sequence >= pstudiohdr->numseq || !pMonsterEvent ) return 0; - int events = 0; - mstudioseqdesc_t *pseqdesc; mstudioevent_t *pevent; @@ -351,7 +349,7 @@ float SetController( void *pmodel, entvars_t *pev, int iController, float flValu } } - int setting = 255 * ( flValue - pbonecontroller->start ) / ( pbonecontroller->end - pbonecontroller->start ); + int setting = (int)( 255 * ( flValue - pbonecontroller->start ) / ( pbonecontroller->end - pbonecontroller->start ) ); if( setting < 0 ) setting = 0; @@ -393,7 +391,7 @@ float SetBlending( void *pmodel, entvars_t *pev, int iBlender, float flValue ) } } - int setting = 255 * ( flValue - pseqdesc->blendstart[iBlender] ) / ( pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender] ); + int setting = (int)( 255 * ( flValue - pseqdesc->blendstart[iBlender] ) / ( pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender] ) ); if( setting < 0 ) setting = 0; diff --git a/dlls/apache.cpp b/dlls/apache.cpp index b64a8bae..aeeea30e 100644 --- a/dlls/apache.cpp +++ b/dlls/apache.cpp @@ -458,7 +458,7 @@ void CApache::HuntThink( void ) if( m_flGoalSpeed < 800 ) m_flGoalSpeed += 5; - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { // ALERT( at_console, "%s\n", STRING( m_hEnemy->pev->classname ) ); if( FVisible( m_hEnemy ) ) @@ -552,7 +552,7 @@ void CApache::HuntThink( void ) { if( m_flLastSeen + 60 > gpGlobals->time ) { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { // make sure it's a good shot if( DotProduct( m_vecTarget, vecEst ) > .965 ) @@ -732,7 +732,6 @@ void CApache::Flight( void ) void CApache::FireRocket( void ) { static float side = 1.0; - static int count; if( m_iRockets <= 0 ) return; diff --git a/dlls/barnacle.cpp b/dlls/barnacle.cpp index 1e2aa785..ecc1f5d4 100644 --- a/dlls/barnacle.cpp +++ b/dlls/barnacle.cpp @@ -170,7 +170,7 @@ void CBarnacle::BarnacleThink( void ) #endif pev->nextthink = gpGlobals->time + 0.1; - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { // barnacle has prey. if( !m_hEnemy->IsAlive() ) @@ -183,7 +183,7 @@ void CBarnacle::BarnacleThink( void ) if( m_fLiftingPrey ) { - if( m_hEnemy != NULL && m_hEnemy->pev->deadflag != DEAD_NO ) + if( m_hEnemy != 0 && m_hEnemy->pev->deadflag != DEAD_NO ) { // crap, someone killed the prey on the way up. m_hEnemy = NULL; @@ -352,7 +352,7 @@ void CBarnacle::Killed( entvars_t *pevAttacker, int iGib ) pev->solid = SOLID_NOT; pev->takedamage = DAMAGE_NO; - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { pVictim = m_hEnemy->MyMonsterPointer(); diff --git a/dlls/barney.cpp b/dlls/barney.cpp index b1c97090..3fc5aef0 100644 --- a/dlls/barney.cpp +++ b/dlls/barney.cpp @@ -221,7 +221,7 @@ void CBarney::RunTask( Task_t *pTask ) switch( pTask->iTask ) { case TASK_RANGE_ATTACK1: - if( m_hEnemy != NULL && ( m_hEnemy->IsPlayer() ) ) + if( m_hEnemy != 0 && ( m_hEnemy->IsPlayer() ) ) { pev->framerate = 1.5; } @@ -262,7 +262,7 @@ int CBarney::Classify( void ) //========================================================= void CBarney::AlertSound( void ) { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { if( FOkToSpeak() ) { @@ -504,7 +504,7 @@ int CBarney::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float // This is a heurstic to determine if the player intended to harm me // If I have an enemy, we can't establish intent (may just be crossfire) - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { // If the player was facing directly at me, or I'm already suspicious, get mad if( ( m_afMemory & bits_MEMORY_SUSPICIOUS ) || IsFacing( pevAttacker, pev->origin ) ) @@ -616,7 +616,7 @@ void CBarney::Killed( entvars_t *pevAttacker, int iGib ) GetAttachment( 0, vecGunPos, vecGunAngles ); - CBaseEntity *pGun = DropItem( "weapon_9mmhandgun", vecGunPos, vecGunAngles ); + DropItem( "weapon_9mmhandgun", vecGunPos, vecGunAngles ); } SetUse( NULL ); @@ -633,7 +633,7 @@ Schedule_t *CBarney::GetScheduleOfType( int Type ) switch( Type ) { case SCHED_ARM_WEAPON: - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { // face enemy, then draw. return slBarneyEnemyDraw; @@ -721,7 +721,7 @@ Schedule_t *CBarney::GetSchedule( void ) return GetScheduleOfType( SCHED_SMALL_FLINCH ); } - if( m_hEnemy == NULL && IsFollowing() ) + if( m_hEnemy == 0 && IsFollowing() ) { if( !m_hTargetEnt->IsAlive() ) { @@ -783,10 +783,10 @@ public: void KeyValue( KeyValueData *pkvd ); int m_iPose;// which sequence to display -- temporary, don't need to save - static char *m_szPoses[3]; + static const char *m_szPoses[3]; }; -char *CDeadBarney::m_szPoses[] = { "lying_on_back", "lying_on_side", "lying_on_stomach" }; +const char *CDeadBarney::m_szPoses[] = { "lying_on_back", "lying_on_side", "lying_on_stomach" }; void CDeadBarney::KeyValue( KeyValueData *pkvd ) { diff --git a/dlls/basemonster.h b/dlls/basemonster.h index ad05fccf..0d22104f 100644 --- a/dlls/basemonster.h +++ b/dlls/basemonster.h @@ -195,7 +195,7 @@ public: Task_t *GetTask( void ); virtual MONSTERSTATE GetIdealState( void ); virtual void SetActivity( Activity NewActivity ); - void SetSequenceByName( char *szSequence ); + void SetSequenceByName( const char *szSequence ); void SetState( MONSTERSTATE State ); virtual void ReportAIState( void ); @@ -327,6 +327,6 @@ public: BOOL ExitScriptedSequence(); BOOL CineCleanup(); - CBaseEntity* DropItem ( char *pszItemName, const Vector &vecPos, const Vector &vecAng );// drop an item. + CBaseEntity* DropItem( const char *pszItemName, const Vector &vecPos, const Vector &vecAng );// drop an item. }; #endif // BASEMONSTER_H diff --git a/dlls/bigmomma.cpp b/dlls/bigmomma.cpp index 59f6cae2..a038c776 100644 --- a/dlls/bigmomma.cpp +++ b/dlls/bigmomma.cpp @@ -677,7 +677,7 @@ void CBigMomma::Precache() void CBigMomma::Activate( void ) { - if( m_hTargetEnt == NULL ) + if( m_hTargetEnt == 0 ) Remember( bits_MEMORY_ADVANCE_NODE ); // Start 'er up } @@ -985,7 +985,7 @@ void CBigMomma::RunTask( Task_t *pTask ) { float distance; - if( m_hTargetEnt == NULL ) + if( m_hTargetEnt == 0 ) TaskFail(); else { @@ -1002,7 +1002,7 @@ void CBigMomma::RunTask( Task_t *pTask ) } break; case TASK_WAIT_NODE: - if( m_hTargetEnt != NULL && ( m_hTargetEnt->pev->spawnflags & SF_INFOBM_WAIT ) ) + if( m_hTargetEnt != 0 && ( m_hTargetEnt->pev->spawnflags & SF_INFOBM_WAIT ) ) return; if( gpGlobals->time > m_flWaitFinished ) @@ -1056,7 +1056,6 @@ Vector VecCheckSplatToss( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot float time = speed / flGravity; vecGrenadeVel = vecSpot2 - vecSpot1; vecGrenadeVel.z = 0; - float distance = vecGrenadeVel.Length(); // Travel half the distance to the target in that time (apex is at the midpoint) vecGrenadeVel = vecGrenadeVel * ( 0.5 / time ); diff --git a/dlls/bmodels.cpp b/dlls/bmodels.cpp index ee676679..6e8526f9 100644 --- a/dlls/bmodels.cpp +++ b/dlls/bmodels.cpp @@ -210,7 +210,7 @@ void CFuncIllusionary::KeyValue( KeyValueData *pkvd ) { if( FStrEq( pkvd->szKeyName, "skin" ) )//skin is used for content type { - pev->skin = atof( pkvd->szValue ); + pev->skin = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else @@ -614,7 +614,7 @@ void CFuncRotating::SpinDown( void ) // stop sound, we're done EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char *)STRING( pev->noiseRunning /* Stop */ ), - 0, 0, SND_STOP, m_pitch ); + 0, 0, SND_STOP, (int)m_pitch ); SetThink( &CFuncRotating::Rotate ); Rotate(); diff --git a/dlls/bullsquid.cpp b/dlls/bullsquid.cpp index 18026b43..af3ab88a 100644 --- a/dlls/bullsquid.cpp +++ b/dlls/bullsquid.cpp @@ -248,7 +248,7 @@ int CBullsquid::IgnoreConditions( void ) iIgnore = bits_COND_SMELL | bits_COND_SMELL_FOOD; } - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { if( FClassnameIs( m_hEnemy->pev, "monster_headcrab" ) ) { @@ -287,7 +287,7 @@ int CBullsquid::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, flo // if the squid is running, has an enemy, was hurt by the enemy, hasn't been hurt in the last 3 seconds, and isn't too close to the enemy, // it will swerve. (whew). - if( m_hEnemy != NULL && IsMoving() && pevAttacker == m_hEnemy->pev && gpGlobals->time - m_flLastHurtTime > 3 ) + if( m_hEnemy != 0 && IsMoving() && pevAttacker == m_hEnemy->pev && gpGlobals->time - m_flLastHurtTime > 3 ) { flDist = ( pev->origin - m_hEnemy->pev->origin ).Length2D(); @@ -324,7 +324,7 @@ BOOL CBullsquid::CheckRangeAttack1( float flDot, float flDist ) if( flDist > 64 && flDist <= 784 && flDot >= 0.5 && gpGlobals->time >= m_flNextSpitTime ) { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { if( fabs( pev->origin.z - m_hEnemy->pev->origin.z ) > 256 ) { @@ -383,7 +383,7 @@ BOOL CBullsquid::CheckMeleeAttack2( float flDot, float flDist ) //========================================================= BOOL CBullsquid::FValidateHintType( short sHint ) { - int i; + size_t i; static short sSquidHints[] = { @@ -784,7 +784,7 @@ void CBullsquid::RunAI( void ) pev->skin = 1; } - if( m_hEnemy != NULL && m_Activity == ACT_RUN ) + if( m_hEnemy != 0 && m_Activity == ACT_RUN ) { // chasing enemy. Sprint for last bit if( ( pev->origin - m_hEnemy->pev->origin).Length2D() < SQUID_SPRINT_DIST ) @@ -1247,7 +1247,7 @@ MONSTERSTATE CBullsquid::GetIdealState( void ) COMBAT goes to ALERT upon death of enemy */ { - if( m_hEnemy != NULL && ( iConditions & bits_COND_LIGHT_DAMAGE || iConditions & bits_COND_HEAVY_DAMAGE ) && FClassnameIs( m_hEnemy->pev, "monster_headcrab" ) ) + if( m_hEnemy != 0 && ( iConditions & bits_COND_LIGHT_DAMAGE || iConditions & bits_COND_HEAVY_DAMAGE ) && FClassnameIs( m_hEnemy->pev, "monster_headcrab" ) ) { // if the squid has a headcrab enemy and something hurts it, it's going to forget about the crab for a while. m_hEnemy = NULL; diff --git a/dlls/buttons.cpp b/dlls/buttons.cpp index 3027f10e..76f4ad91 100644 --- a/dlls/buttons.cpp +++ b/dlls/buttons.cpp @@ -275,7 +275,7 @@ IMPLEMENT_SAVERESTORE( CBaseButton, CBaseToggle ) void CBaseButton::Precache( void ) { - char *pszSound; + const char *pszSound; if( FBitSet( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) )// this button should spark in OFF state { @@ -381,22 +381,22 @@ void CBaseButton::KeyValue( KeyValueData *pkvd ) } else if( FStrEq( pkvd->szKeyName, "locked_sound" ) ) { - m_bLockedSound = atof( pkvd->szValue ); + m_bLockedSound = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "locked_sentence" ) ) { - m_bLockedSentence = atof( pkvd->szValue ); + m_bLockedSentence = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "unlocked_sound" ) ) { - m_bUnlockedSound = atof( pkvd->szValue ); + m_bUnlockedSound = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "unlocked_sentence" ) ) { - m_bUnlockedSentence = atof( pkvd->szValue ); + m_bUnlockedSentence = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "sounds" ) ) @@ -421,7 +421,7 @@ int CBaseButton::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, fl SetTouch( NULL ); m_hActivator = CBaseEntity::Instance( pevAttacker ); - if( m_hActivator == NULL ) + if( m_hActivator == 0 ) return 0; if( code == BUTTON_RETURN ) @@ -461,7 +461,7 @@ LINK_ENTITY_TO_CLASS( func_button, CBaseButton ) void CBaseButton::Spawn() { - char *pszSound; + const char *pszSound; //---------------------------------------------------- //determine sounds for buttons @@ -527,7 +527,7 @@ void CBaseButton::Spawn() char *ButtonSound( int sound ) { - char *pszSound; + const char *pszSound; switch( sound ) { @@ -869,7 +869,7 @@ LINK_ENTITY_TO_CLASS( func_rot_button, CRotButton ) void CRotButton::Spawn( void ) { - char *pszSound; + const char *pszSound; //---------------------------------------------------- //determine sounds for buttons //a sound of 0 should not make a sound @@ -1010,7 +1010,7 @@ void CMomentaryRotButton::Spawn( void ) UTIL_SetOrigin( pev, pev->origin ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); - char *pszSound = ButtonSound( m_sounds ); + const char *pszSound = ButtonSound( m_sounds ); PRECACHE_SOUND( pszSound ); pev->noise = ALLOC_STRING( pszSound ); m_lastUsed = 0; diff --git a/dlls/cbase.cpp b/dlls/cbase.cpp index 62b4eaa1..0cc10bdb 100644 --- a/dlls/cbase.cpp +++ b/dlls/cbase.cpp @@ -26,7 +26,7 @@ void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ); extern "C" void PM_Move ( struct playermove_s *ppmove, int server ); extern "C" void PM_Init ( struct playermove_s *ppmove ); -extern "C" char PM_FindTextureType( char *name ); +extern "C" char PM_FindTextureType( const char *name ); extern Vector VecBModelOrigin( entvars_t* pevBModel ); extern DLL_GLOBAL Vector g_vecAttackDir; @@ -739,7 +739,7 @@ int CBaseEntity::DamageDecal( int bitsDamageType ) // NOTE: szName must be a pointer to constant memory, e.g. "monster_class" because the entity // will keep a pointer to it after this call. -CBaseEntity *CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) +CBaseEntity *CBaseEntity::Create( const char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) { edict_t *pent; CBaseEntity *pEntity; diff --git a/dlls/cbase.h b/dlls/cbase.h index 617bbab9..6c738bf5 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -177,7 +177,7 @@ public: virtual void AddPointsToTeam( int score, BOOL bAllowNegativeScore ) {} virtual BOOL AddPlayerItem( CBasePlayerItem *pItem ) { return 0; } virtual BOOL RemovePlayerItem( CBasePlayerItem *pItem ) { return 0; } - virtual int GiveAmmo( int iAmount, char *szName, int iMax ) { return -1; }; + virtual int GiveAmmo( int iAmount, const char *szName, int iMax ) { return -1; }; virtual float GetDelay( void ) { return 0; } virtual int IsMoving( void ) { return pev->velocity != g_vecZero; } virtual void OverrideReset( void ) {} @@ -314,7 +314,7 @@ public: // used by monsters that are created by the MonsterMaker virtual void UpdateOwner( void ) { return; }; - static CBaseEntity *Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = NULL ); + static CBaseEntity *Create( const char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = NULL ); virtual BOOL FBecomeProne( void ) {return FALSE;}; edict_t *edict() { return ENT( pev ); }; @@ -655,8 +655,7 @@ class CSound; #include "basemonster.h" - -char *ButtonSound( int sound ); // get string of button sound number +const char *ButtonSound( int sound ); // get string of button sound number // // Generic Button diff --git a/dlls/client.cpp b/dlls/client.cpp index 72538b02..99f1913b 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -215,7 +215,7 @@ bool Q_IsValidUChar32( unsigned int uVal ) { // Values > 0x10FFFF are explicitly invalid; ditto for UTF-16 surrogate halves, // values ending in FFFE or FFFF, or values in the 0x00FDD0-0x00FDEF reserved range - return ( uVal < 0x110000u ) && ( ( uVal - 0x00D800u ) > 0x7FFu ) && ( ( uVal & 0xFFFFu ) < 0xFFFEu ) && ( ( uVal - 0x00FDD0u ) > 0x1Fu ); + return ( ( uVal - 0x0u ) < 0x110000u ) && ( (uVal - 0x00D800u) > 0x7FFu ) && ( (uVal & 0xFFFFu) < 0xFFFEu ) && ( ( uVal - 0x00FDD0u ) > 0x1Fu ); } // Decode one character from a UTF-8 encoded string. Treats 6-byte CESU-8 sequences @@ -423,7 +423,7 @@ void Host_Say( edict_t *pEntity, int teamonly ) // echo to server console g_engfuncs.pfnServerPrint( text ); - char *temp; + const char *temp; if( teamonly ) temp = "say_team"; else @@ -744,7 +744,6 @@ void PlayerPreThink( edict_t *pEntity ) { //ALERT( at_console, "PreThink( %g, frametime %g )\n", gpGlobals->time, gpGlobals->frametime ); - entvars_t *pev = &pEntity->v; CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE( pEntity ); if( pPlayer ) @@ -762,7 +761,6 @@ void PlayerPostThink( edict_t *pEntity ) { //ALERT( at_console, "PostThink( %g, frametime %g )\n", gpGlobals->time, gpGlobals->frametime ); - entvars_t *pev = &pEntity->v; CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE( pEntity ); if( pPlayer ) @@ -950,7 +948,6 @@ animation right now. */ void PlayerCustomization( edict_t *pEntity, customization_t *pCust ) { - entvars_t *pev = &pEntity->v; CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE( pEntity ); if( !pPlayer ) @@ -990,7 +987,6 @@ A spectator has joined the game */ void SpectatorConnect( edict_t *pEntity ) { - entvars_t *pev = &pEntity->v; CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE( pEntity ); if( pPlayer ) @@ -1006,7 +1002,6 @@ A spectator has left the game */ void SpectatorDisconnect( edict_t *pEntity ) { - entvars_t *pev = &pEntity->v; CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE( pEntity ); if( pPlayer ) @@ -1022,7 +1017,6 @@ A spectator has sent a usercmd */ void SpectatorThink( edict_t *pEntity ) { - entvars_t *pev = &pEntity->v; CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE( pEntity ); if( pPlayer ) @@ -1235,11 +1229,11 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h } state->rendermode = ent->v.rendermode; - state->renderamt = ent->v.renderamt; + state->renderamt = (int)ent->v.renderamt; state->renderfx = ent->v.renderfx; - state->rendercolor.r = ent->v.rendercolor.x; - state->rendercolor.g = ent->v.rendercolor.y; - state->rendercolor.b = ent->v.rendercolor.z; + state->rendercolor.r = (byte)ent->v.rendercolor.x; + state->rendercolor.g = (byte)ent->v.rendercolor.y; + state->rendercolor.b = (byte)ent->v.rendercolor.z; state->aiment = 0; if( ent->v.aiment ) @@ -1286,7 +1280,7 @@ int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *h //state->team = ent->v.team; state->usehull = ( ent->v.flags & FL_DUCKING ) ? 1 : 0; - state->health = ent->v.health; + state->health = (int)ent->v.health; } return 1; @@ -1834,7 +1828,7 @@ ConnectionlessPacket int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ) { // Parse stuff from args - int max_buffer_size = *response_buffer_size; + //int max_buffer_size = *response_buffer_size; // Zero it out since we aren't going to respond. // If we wanted to response, we'd write data into response_buffer @@ -1888,10 +1882,10 @@ to be created during play ( e.g., grenades, ammo packs, projectiles, corpses, et */ void CreateInstancedBaselines( void ) { - int iret = 0; + /*int iret = 0; entity_state_t state; - memset( &state, 0, sizeof(state) ); + memset( &state, 0, sizeof(state) );*/ // Create any additional baselines here for things like grendates, etc. // iret = ENGINE_INSTANCE_BASELINE( pc->pev->classname, &state ); diff --git a/dlls/combat.cpp b/dlls/combat.cpp index 3a59844f..d8830c20 100644 --- a/dlls/combat.cpp +++ b/dlls/combat.cpp @@ -460,11 +460,11 @@ Activity CBaseMonster::GetSmallFlinchActivity( void ) { Activity flinchActivity; BOOL fTriedDirection; - float flDot; + //float flDot; fTriedDirection = FALSE; UTIL_MakeVectors( pev->angles ); - flDot = DotProduct( gpGlobals->v_forward, g_vecAttackDir * -1 ); + //flDot = DotProduct( gpGlobals->v_forward, g_vecAttackDir * -1 ); switch( m_LastHitGroup ) { @@ -576,8 +576,8 @@ Killed */ void CBaseMonster::Killed( entvars_t *pevAttacker, int iGib ) { - unsigned int cCount = 0; - BOOL fDone = FALSE; + //unsigned int cCount = 0; + //BOOL fDone = FALSE; if( HasMemory( bits_MEMORY_KILLED ) ) { @@ -920,7 +920,7 @@ int CBaseMonster::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, f // enemy's last known position is somewhere down the vector that the attack came from. if( pevInflictor ) { - if( m_hEnemy == NULL || pevInflictor == m_hEnemy->pev || !HasConditions( bits_COND_SEE_ENEMY ) ) + if( m_hEnemy == 0 || pevInflictor == m_hEnemy->pev || !HasConditions( bits_COND_SEE_ENEMY ) ) { m_vecEnemyLKP = pevInflictor->origin; } @@ -1463,7 +1463,7 @@ void CBaseEntity::FireBullets( ULONG cShots, Vector vecSrc, Vector vecDirShootin } } // make bullet trails - UTIL_BubbleTrail( vecSrc, tr.vecEndPos, ( flDistance * tr.flFraction ) / 64.0 ); + UTIL_BubbleTrail( vecSrc, tr.vecEndPos, (int)( ( flDistance * tr.flFraction ) / 64.0 ); } ApplyMultiDamage( pev, pevAttacker ); } @@ -1483,7 +1483,8 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi TraceResult tr; Vector vecRight = gpGlobals->v_right; Vector vecUp = gpGlobals->v_up; - float x, y, z; + float x = 0.0f, y = 0.0f; + float z; if( pevAttacker == NULL ) pevAttacker = pev; // the default attacker is ourselves @@ -1497,7 +1498,7 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi // get circular gaussian spread x = UTIL_SharedRandomFloat( shared_rand + iShot, -0.5, 0.5 ) + UTIL_SharedRandomFloat( shared_rand + ( 1 + iShot ) , -0.5, 0.5 ); y = UTIL_SharedRandomFloat( shared_rand + ( 2 + iShot ), -0.5, 0.5 ) + UTIL_SharedRandomFloat( shared_rand + ( 3 + iShot ), -0.5, 0.5 ); - z = x * x + y * y; + //z = x * x + y * y; Vector vecDir = vecDirShooting + x * vecSpread.x * vecRight + @@ -1548,7 +1549,7 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi } } // make bullet trails - UTIL_BubbleTrail( vecSrc, tr.vecEndPos, ( flDistance * tr.flFraction ) / 64.0 ); + UTIL_BubbleTrail( vecSrc, tr.vecEndPos, (int)( ( flDistance * tr.flFraction ) / 64.0 ) ); } ApplyMultiDamage( pev, pevAttacker ); diff --git a/dlls/controller.cpp b/dlls/controller.cpp index 3d56325f..bfa119d3 100644 --- a/dlls/controller.cpp +++ b/dlls/controller.cpp @@ -614,7 +614,7 @@ void CController::RunTask( Task_t *pTask ) Vector vecSrc = vecHand + pev->velocity * ( m_flShootTime - gpGlobals->time ); Vector vecDir; - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { if( HasConditions( bits_COND_SEE_ENEMY ) ) { @@ -707,7 +707,7 @@ Schedule_t *CController::GetSchedule( void ) { case MONSTERSTATE_COMBAT: { - Vector vecTmp = Intersect( Vector( 0, 0, 0 ), Vector( 100, 4, 7 ), Vector( 2, 10, -3 ), 20.0 ); + // Vector vecTmp = Intersect( Vector( 0, 0, 0 ), Vector( 100, 4, 7 ), Vector( 2, 10, -3 ), 20.0 ); // dead enemy if( HasConditions( bits_COND_LIGHT_DAMAGE ) ) @@ -1095,7 +1095,6 @@ class CControllerHeadBall : public CBaseMonster void EXPORT BounceTouch( CBaseEntity *pOther ); void MovetoTarget( Vector vecTarget ); void Crawl( void ); - int m_iTrail; int m_flNextAttack; Vector m_vecIdeal; EHANDLE m_hOwner; @@ -1160,7 +1159,7 @@ void CControllerHeadBall::HuntThink( void ) MESSAGE_END(); // check world boundaries - if( gpGlobals->time - pev->dmgtime > 5 || pev->renderamt < 64 || m_hEnemy == NULL || m_hOwner == NULL || pev->origin.x < -4096 || pev->origin.x > 4096 || pev->origin.y < -4096 || pev->origin.y > 4096 || pev->origin.z < -4096 || pev->origin.z > 4096 ) + if( gpGlobals->time - pev->dmgtime > 5 || pev->renderamt < 64 || m_hEnemy == 0 || m_hOwner == 0 || pev->origin.x < -4096 || pev->origin.x > 4096 || pev->origin.y < -4096 || pev->origin.y > 4096 || pev->origin.z < -4096 || pev->origin.z > 4096 ) { SetTouch( NULL ); UTIL_Remove( this ); @@ -1340,7 +1339,7 @@ void CControllerZapBall::ExplodeTouch( CBaseEntity *pOther ) entvars_t *pevOwner; - if( m_hOwner != NULL ) + if( m_hOwner != 0 ) { pevOwner = m_hOwner->pev; } diff --git a/dlls/crossbow.cpp b/dlls/crossbow.cpp index 7a4686e7..d749c785 100644 --- a/dlls/crossbow.cpp +++ b/dlls/crossbow.cpp @@ -425,10 +425,11 @@ void CCrossbow::FireBolt() UTIL_MakeVectors( anglesAim ); anglesAim.x = -anglesAim.x; + +#ifndef CLIENT_DLL Vector vecSrc = m_pPlayer->GetGunPosition() - gpGlobals->v_up * 2; Vector vecDir = gpGlobals->v_forward; -#ifndef CLIENT_DLL CCrossbowBolt *pBolt = CCrossbowBolt::BoltCreate(); pBolt->pev->origin = vecSrc; pBolt->pev->angles = anglesAim; diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index 80a18d65..00b16d57 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -183,7 +183,7 @@ int CCrowbar::Swing( int fFirst ) #endif PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usCrowbar, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, - 0.0, 0, 0.0 ); + 0, 0, 0 ); if( tr.flFraction >= 1.0 ) { @@ -294,7 +294,7 @@ int CCrowbar::Swing( int fFirst ) m_trHit = tr; } - m_pPlayer->m_iWeaponVolume = flVol * CROWBAR_WALLHIT_VOLUME; + m_pPlayer->m_iWeaponVolume = (int)( flVol * CROWBAR_WALLHIT_VOLUME ); #endif m_flNextPrimaryAttack = GetNextAttackDelay( 0.25 ); diff --git a/dlls/decals.h b/dlls/decals.h index ce5a2b53..97f5f29f 100644 --- a/dlls/decals.h +++ b/dlls/decals.h @@ -66,7 +66,7 @@ enum decal_e typedef struct { - char *name; + const char *name; int index; } DLL_DECALLIST; diff --git a/dlls/doors.cpp b/dlls/doors.cpp index bdc82f06..dcb04e00 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -189,42 +189,42 @@ void CBaseDoor::KeyValue( KeyValueData *pkvd ) { if( FStrEq( pkvd->szKeyName, "skin" ) )//skin is used for content type { - pev->skin = atof( pkvd->szValue ); + pev->skin = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "movesnd" ) ) { - m_bMoveSnd = atof( pkvd->szValue ); + m_bMoveSnd = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "stopsnd" ) ) { - m_bStopSnd = atof( pkvd->szValue ); + m_bStopSnd = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "healthvalue" ) ) { - m_bHealthValue = atof( pkvd->szValue ); + m_bHealthValue = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "locked_sound" ) ) { - m_bLockedSound = atof( pkvd->szValue ); + m_bLockedSound = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "locked_sentence" ) ) { - m_bLockedSentence = atof( pkvd->szValue ); + m_bLockedSentence = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "unlocked_sound" ) ) { - m_bUnlockedSound = atof( pkvd->szValue ); + m_bUnlockedSound = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "unlocked_sentence" ) ) { - m_bUnlockedSentence = atof( pkvd->szValue ); + m_bUnlockedSentence = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "WaveHeight" ) ) @@ -328,7 +328,7 @@ void CBaseDoor::SetToggleState( int state ) void CBaseDoor::Precache( void ) { - char *pszSound; + const char *pszSound; // set the door's "in-motion" sound switch( m_bMoveSnd ) @@ -581,7 +581,7 @@ int CBaseDoor::DoorActivate() else { // door should open - if( m_hActivator != NULL && m_hActivator->IsPlayer() ) + if( m_hActivator != 0 && m_hActivator->IsPlayer() ) { // give health if player opened the door (medikit) //VARS( m_eoActivator )->health += m_bHealthValue; @@ -623,7 +623,7 @@ void CBaseDoor::DoorGoUp( void ) { float sign = 1.0; - if( m_hActivator != NULL ) + if( m_hActivator != 0 ) { pevActivator = m_hActivator->pev; @@ -1070,7 +1070,7 @@ void CMomentaryDoor::KeyValue( KeyValueData *pkvd ) if( FStrEq( pkvd->szKeyName, "movesnd" ) ) { - m_bMoveSnd = atof( pkvd->szValue ); + m_bMoveSnd = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "stopsnd" ) ) diff --git a/dlls/effects.cpp b/dlls/effects.cpp index ecc04a19..2977a3ed 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -75,7 +75,7 @@ void CBubbling::Spawn( void ) pev->solid = SOLID_NOT; // Remove model & collisions pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on pev->rendermode = kRenderTransTexture; - int speed = pev->speed > 0 ? pev->speed : -pev->speed; + int speed = fabs( pev->speed ); // HACKHACK!!! - Speed in rendercolor pev->rendercolor.x = speed >> 8; @@ -701,7 +701,7 @@ void CLightning::StrikeThink( void ) WRITE_BYTE( (int)pev->rendercolor.x ); // r, g, b WRITE_BYTE( (int)pev->rendercolor.y ); // r, g, b WRITE_BYTE( (int)pev->rendercolor.z ); // r, g, b - WRITE_BYTE( pev->renderamt ); // brightness + WRITE_BYTE( (int)pev->renderamt ); // brightness WRITE_BYTE( m_speed ); // speed MESSAGE_END(); DoSparks( pStart->pev->origin, pEnd->pev->origin ); @@ -763,7 +763,7 @@ void CLightning::Zap( const Vector &vecSrc, const Vector &vecDest ) WRITE_BYTE( (int)pev->rendercolor.x ); // r, g, b WRITE_BYTE( (int)pev->rendercolor.y ); // r, g, b WRITE_BYTE( (int)pev->rendercolor.z ); // r, g, b - WRITE_BYTE( pev->renderamt ); // brightness + WRITE_BYTE( (int)pev->renderamt ); // brightness WRITE_BYTE( m_speed ); // speed MESSAGE_END(); #else @@ -944,7 +944,7 @@ void CLaser::Spawn( void ) m_pSprite = NULL; if( m_pSprite ) - m_pSprite->SetTransparency( kRenderGlow, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, pev->renderamt, pev->renderfx ); + m_pSprite->SetTransparency( kRenderGlow, (int)pev->rendercolor.x, (int)pev->rendercolor.y, (int)pev->rendercolor.z, (int)pev->renderamt, (int)pev->renderfx ); if( pev->targetname && !( pev->spawnflags & SF_BEAM_STARTON ) ) TurnOff(); @@ -1619,7 +1619,7 @@ void CTestEffect::TestThink( void ) for( i = 0; i < m_iBeam; i++ ) { t = ( gpGlobals->time - m_flBeamTime[i] ) / ( 3 + m_flStartTime - m_flBeamTime[i] ); - m_pBeam[i]->SetBrightness( 255 * t ); + m_pBeam[i]->SetBrightness( (int)( 255 * t ) ); // m_pBeam[i]->SetScrollRate( 20 * t ); } pev->nextthink = gpGlobals->time + 0.1; @@ -1749,9 +1749,9 @@ Vector CBlood::BloodPosition( CBaseEntity *pActivator ) void CBlood::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { if( pev->spawnflags & SF_BLOOD_STREAM ) - UTIL_BloodStream( BloodPosition( pActivator ), Direction(), ( Color() == BLOOD_COLOR_RED ) ? 70 : Color(), BloodAmount() ); + UTIL_BloodStream( BloodPosition( pActivator ), Direction(), ( Color() == BLOOD_COLOR_RED ) ? 70 : Color(), (int)BloodAmount() ); else - UTIL_BloodDrips( BloodPosition( pActivator ), Direction(), Color(), BloodAmount() ); + UTIL_BloodDrips( BloodPosition( pActivator ), Direction(), Color(), (int)BloodAmount() ); if( pev->spawnflags & SF_BLOOD_DECAL ) { @@ -1947,12 +1947,12 @@ void CFade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType { if( pActivator->IsNetClient() ) { - UTIL_ScreenFade( pActivator, pev->rendercolor, Duration(), HoldTime(), pev->renderamt, fadeFlags ); + UTIL_ScreenFade( pActivator, pev->rendercolor, Duration(), HoldTime(), (int)pev->renderamt, fadeFlags ); } } else { - UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), pev->renderamt, fadeFlags ); + UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), (int)pev->renderamt, fadeFlags ); } SUB_UseTargets( this, USE_TOGGLE, 0 ); } diff --git a/dlls/effects.h b/dlls/effects.h index 031b8273..68f0ea29 100644 --- a/dlls/effects.h +++ b/dlls/effects.h @@ -238,7 +238,7 @@ public: inline int GetWidth( void ) { - return pev->scale; + return (int)pev->scale; } inline int GetNoise( void ) @@ -255,17 +255,17 @@ public: inline int GetBrightness( void ) { - return pev->renderamt; + return (int)pev->renderamt; } inline int GetFrame( void ) { - return pev->frame; + return (int)pev->frame; } inline int GetScrollRate( void ) { - return pev->animtime; + return (int)pev->animtime; } // Call after you change start/end positions diff --git a/dlls/egon.cpp b/dlls/egon.cpp index 433704ce..9a4de49b 100644 --- a/dlls/egon.cpp +++ b/dlls/egon.cpp @@ -270,7 +270,7 @@ void CEgon::Fire( const Vector &vecOrigSrc, const Vector &vecDir ) } } #endif - float timedist; + float timedist = 0.0f; switch( m_fireMode ) { @@ -380,13 +380,13 @@ void CEgon::UpdateEffect( const Vector &startPoint, const Vector &endPoint, floa } m_pBeam->SetStartPos( endPoint ); - m_pBeam->SetBrightness( 255 - ( timeBlend * 180 ) ); - m_pBeam->SetWidth( 40 - ( timeBlend * 20 ) ); + m_pBeam->SetBrightness( (int)( 255 - ( timeBlend * 180 )) ); + m_pBeam->SetWidth( (int)( 40 - ( timeBlend * 20 ) ) ); if( m_fireMode == FIRE_WIDE ) - m_pBeam->SetColor( 30 + ( 25 * timeBlend ), 30 + ( 30 * timeBlend ), 64 + 80 * fabs( sin( gpGlobals->time * 10 ) ) ); + m_pBeam->SetColor( (int)( 30 + ( 25 * timeBlend ) ), (int)( 30 + ( 30 * timeBlend ) ), (int)( 64 + 80 * fabs( sin( gpGlobals->time * 10 ) ) ) ); else - m_pBeam->SetColor( 60 + ( 25 * timeBlend ), 120 + ( 30 * timeBlend ), 64 + 80 * fabs( sin( gpGlobals->time *10 ) ) ); + m_pBeam->SetColor( (int)( 60 + ( 25 * timeBlend ) ), (int)( 120 + ( 30 * timeBlend ) ), (int)( 64 + 80 * fabs( sin( gpGlobals->time *10 ) ) ) ); UTIL_SetOrigin( m_pSprite->pev, endPoint ); m_pSprite->pev->frame += 8 * gpGlobals->frametime; diff --git a/dlls/enginecallback.h b/dlls/enginecallback.h index 1c5ec1b2..9bef0d48 100644 --- a/dlls/enginecallback.h +++ b/dlls/enginecallback.h @@ -14,10 +14,18 @@ ****/ #ifndef ENGINECALLBACK_H #define ENGINECALLBACK_H + +#ifdef _WIN32 +#ifndef __MINGW32__ #pragma once +#endif /* not __MINGW32__ */ +#endif #include "event_flags.h" +// Fix warning in MSVC8 +#undef SERVER_EXECUTE + // Must be provided by user of this code extern enginefuncs_t g_engfuncs; diff --git a/dlls/extdll.h b/dlls/extdll.h index 58349e32..ea176aab 100644 --- a/dlls/extdll.h +++ b/dlls/extdll.h @@ -25,11 +25,13 @@ #endif // Silence certain warnings +#ifdef _MSC_VER #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 : 4514) // unreferenced inline function removed #pragma warning(disable : 4100) // unreferenced formal parameter +#endif // Prevent tons of unused windows definitions #ifdef _WIN32 @@ -42,8 +44,12 @@ #include "windows.h" #undef HSPRITE #else // _WIN32 +#ifndef FALSE #define FALSE 0 +#endif +#ifndef TRUE #define TRUE (!FALSE) +#endif typedef unsigned int ULONG; typedef unsigned char BYTE; typedef int BOOL; diff --git a/dlls/func_break.cpp b/dlls/func_break.cpp index 38b05f7b..6abf1b44 100644 --- a/dlls/func_break.cpp +++ b/dlls/func_break.cpp @@ -104,7 +104,7 @@ void CBreakable::KeyValue( KeyValueData* pkvd ) else if( FStrEq( pkvd->szKeyName, "spawnobject" ) ) { int object = atoi( pkvd->szValue ); - if( object > 0 && object < ARRAYSIZE( pSpawnObjects ) ) + if( object > 0 && object < (int)ARRAYSIZE( pSpawnObjects ) ) m_iszSpawnObject = MAKE_STRING( pSpawnObjects[object] ); pkvd->fHandled = TRUE; } @@ -353,7 +353,7 @@ void CBreakable::DamageSound( void ) { int pitch; float fvol; - char *rgpsz[6]; + const char *rgpsz[6]; int i = 0; int material = m_Material; @@ -574,7 +574,6 @@ void CBreakable::Die( void ) { Vector vecSpot;// shard origin Vector vecVelocity;// shard velocity - CBaseEntity *pEntity = NULL; char cFlag = 0; int pitch; float fvol; @@ -794,7 +793,7 @@ public: static TYPEDESCRIPTION m_SaveData[]; - static char *m_soundNames[3]; + static const char *m_soundNames[3]; int m_lastSound; // no need to save/restore, just keeps the same sound from playing twice in a row float m_maxSpeed; float m_soundTime; @@ -810,7 +809,7 @@ IMPLEMENT_SAVERESTORE( CPushable, CBreakable ) LINK_ENTITY_TO_CLASS( func_pushable, CPushable ) -char *CPushable::m_soundNames[3] = +const char *CPushable::m_soundNames[3] = { "debris/pushbox1.wav", "debris/pushbox2.wav", @@ -839,7 +838,7 @@ void CPushable::Spawn( void ) UTIL_SetOrigin( pev, pev->origin ); // Multiply by area of the box's cross-section (assume 1000 units^3 standard volume) - pev->skin = ( pev->skin * ( pev->maxs.x - pev->mins.x ) * ( pev->maxs.y - pev->mins.y ) ) * 0.0005; + pev->skin = (int)( ( pev->skin * ( pev->maxs.x - pev->mins.x ) * ( pev->maxs.y - pev->mins.y ) ) * 0.0005 ); m_soundTime = 0; } @@ -882,7 +881,7 @@ void CPushable::KeyValue( KeyValueData *pkvd ) } else if( FStrEq( pkvd->szKeyName, "buoyancy" ) ) { - pev->skin = atof( pkvd->szValue ); + pev->skin = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else diff --git a/dlls/func_tank.cpp b/dlls/func_tank.cpp index eab9e621..ab295e0c 100644 --- a/dlls/func_tank.cpp +++ b/dlls/func_tank.cpp @@ -190,7 +190,7 @@ void CFuncTank::Spawn( void ) if( m_fireRate <= 0 ) m_fireRate = 1; - if( m_spread > MAX_FIRING_SPREADS ) + if( m_spread > (int)MAX_FIRING_SPREADS ) m_spread = 0; pev->oldorigin = pev->origin; @@ -328,7 +328,7 @@ BOOL CFuncTank::OnControls( entvars_t *pevTest ) if( !( pev->spawnflags & SF_TANK_CANCONTROL ) ) return FALSE; - Vector offset = pevTest->origin - pev->origin; + //Vector offset = pevTest->origin - pev->origin; if( ( m_vecControllerUsePos - pevTest->origin ).Length() < 30 ) return TRUE; @@ -476,9 +476,9 @@ void CFuncTank::TrackTarget( void ) { TraceResult tr; edict_t *pPlayer = FIND_CLIENT_IN_PVS( edict() ); - BOOL updateTime = FALSE, lineOfSight; + BOOL updateTime = FALSE; Vector angles, direction, targetPosition, barrelEnd; - edict_t *pTarget; + edict_t *pTarget = NULL; // Get a position to aim for if( m_pController ) @@ -515,12 +515,8 @@ void CFuncTank::TrackTarget( void ) UTIL_TraceLine( barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr ); - lineOfSight = FALSE; - // No line of sight, don't track if( tr.flFraction == 1.0 || tr.pHit == pTarget ) { - lineOfSight = TRUE; - CBaseEntity *pInstance = CBaseEntity::Instance(pTarget); if( InRange( range ) && pInstance && pInstance->IsAlive() ) { @@ -644,7 +640,7 @@ void CFuncTank::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t { CSprite *pSprite = CSprite::SpriteCreate( STRING( m_iszSpriteSmoke ), barrelEnd, TRUE ); pSprite->AnimateAndDie( RANDOM_FLOAT( 15.0, 20.0 ) ); - pSprite->SetTransparency( kRenderTransAlpha, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, 255, kRenderFxNone ); + pSprite->SetTransparency( kRenderTransAlpha, (int)pev->rendercolor.x, (int)pev->rendercolor.y, (int)pev->rendercolor.z, 255, kRenderFxNone ); pSprite->pev->velocity.z = RANDOM_FLOAT( 40, 80 ); pSprite->SetScale( m_spriteScale ); } @@ -714,7 +710,7 @@ void CFuncTankGun::Fire( const Vector &barrelEnd, const Vector &forward, entvars // FireBullets needs gpGlobals->v_up, etc. UTIL_MakeAimVectors( pev->angles ); - int bulletCount = ( gpGlobals->time - m_fireLast ) * m_fireRate; + int bulletCount = (int)( ( gpGlobals->time - m_fireLast ) * m_fireRate ); if( bulletCount > 0 ) { for( i = 0; i < bulletCount; i++ ) @@ -835,7 +831,7 @@ void CFuncTankLaser::Fire( const Vector &barrelEnd, const Vector &forward, entva // TankTrace needs gpGlobals->v_up, etc. UTIL_MakeAimVectors( pev->angles ); - int bulletCount = ( gpGlobals->time - m_fireLast ) * m_fireRate; + int bulletCount = (int)( ( gpGlobals->time - m_fireLast ) * m_fireRate ); if( bulletCount ) { for( i = 0; i < bulletCount; i++ ) @@ -879,12 +875,12 @@ void CFuncTankRocket::Fire( const Vector &barrelEnd, const Vector &forward, entv if( m_fireLast != 0 ) { - int bulletCount = ( gpGlobals->time - m_fireLast ) * m_fireRate; + int bulletCount = (int)( ( gpGlobals->time - m_fireLast ) * m_fireRate ); if( bulletCount > 0 ) { for( i = 0; i < bulletCount; i++ ) { - CBaseEntity *pRocket = CBaseEntity::Create( "rpg_rocket", barrelEnd, pev->angles, edict() ); + CBaseEntity::Create( "rpg_rocket", barrelEnd, pev->angles, edict() ); } CFuncTank::Fire( barrelEnd, forward, pev ); } @@ -917,7 +913,7 @@ void CFuncTankMortar::Fire( const Vector &barrelEnd, const Vector &forward, entv { if( m_fireLast != 0 ) { - int bulletCount = ( gpGlobals->time - m_fireLast ) * m_fireRate; + int bulletCount = (int)( ( gpGlobals->time - m_fireLast ) * m_fireRate ); // Only create 1 explosion if( bulletCount > 0 ) { diff --git a/dlls/gargantua.cpp b/dlls/gargantua.cpp index 6c65b06f..7f60b401 100644 --- a/dlls/gargantua.cpp +++ b/dlls/gargantua.cpp @@ -538,7 +538,6 @@ void CGargantua::FlameControls( float angleX, float angleY ) void CGargantua::FlameUpdate( void ) { int i; - static float offset[2] = { 60, -60 }; TraceResult trace; Vector vecStart, angleGun; BOOL streaks = FALSE; @@ -759,7 +758,7 @@ void CGargantua::Spawn() //========================================================= void CGargantua::Precache() { - int i; + size_t i; PRECACHE_MODEL( "models/garg.mdl" ); PRECACHE_MODEL( GARG_EYE_SPRITE_NAME ); diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index 10149202..93352b57 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -259,7 +259,7 @@ void CGauss::SecondaryAttack() m_pPlayer->m_flNextAmmoBurn = 1000; } - int pitch = ( gpGlobals->time - m_pPlayer->m_flStartCharge ) * ( 150 / GetFullChargeTime() ) + 100; + int pitch = (int)( ( gpGlobals->time - m_pPlayer->m_flStartCharge ) * ( 150 / GetFullChargeTime() ) + 100 ); if( pitch > 250 ) pitch = 250; @@ -359,11 +359,11 @@ void CGauss::StartFire( void ) void CGauss::Fire( Vector vecOrigSrc, Vector vecDir, float flDamage ) { m_pPlayer->m_iWeaponVolume = GAUSS_PRIMARY_FIRE_VOLUME; - + TraceResult tr, beam_tr; +#ifndef CLIENT_DLL Vector vecSrc = vecOrigSrc; Vector vecDest = vecSrc + vecDir * 8192; edict_t *pentIgnore; - TraceResult tr, beam_tr; float flMaxFrac = 1.0; int nTotal = 0; int fHasPunched = 0; @@ -371,8 +371,7 @@ void CGauss::Fire( Vector vecOrigSrc, Vector vecDir, float flDamage ) int nMaxHits = 10; pentIgnore = ENT( m_pPlayer->pev ); - -#ifdef CLIENT_DLL +#else if( m_fPrimaryFire == false ) g_irunninggausspred = true; #endif diff --git a/dlls/genericmonster.cpp b/dlls/genericmonster.cpp index c40bb802..23622120 100644 --- a/dlls/genericmonster.cpp +++ b/dlls/genericmonster.cpp @@ -88,7 +88,7 @@ void CGenericMonster::HandleAnimEvent( MonsterEvent_t *pEvent ) //========================================================= int CGenericMonster::ISoundMask( void ) { - return NULL; + return 0; } //========================================================= diff --git a/dlls/ggrenade.cpp b/dlls/ggrenade.cpp index 64d9f3cf..0ca516c4 100644 --- a/dlls/ggrenade.cpp +++ b/dlls/ggrenade.cpp @@ -49,7 +49,7 @@ void CGrenade::Explode( Vector vecSrc, Vector vecAim ) // UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution. void CGrenade::Explode( TraceResult *pTrace, int bitsDamageType ) { - float flRndSound;// sound randomizer + // float flRndSound;// sound randomizer pev->model = iStringNull;//invisible pev->solid = SOLID_NOT;// intangible @@ -102,7 +102,7 @@ void CGrenade::Explode( TraceResult *pTrace, int bitsDamageType ) UTIL_DecalTrace( pTrace, DECAL_SCORCH2 ); } - flRndSound = RANDOM_FLOAT( 0, 1 ); + //flRndSound = RANDOM_FLOAT( 0, 1 ); switch( RANDOM_LONG( 0, 2 ) ) { @@ -144,8 +144,8 @@ void CGrenade::Smoke( void ) WRITE_COORD( pev->origin.y ); WRITE_COORD( pev->origin.z ); WRITE_SHORT( g_sModelIndexSmoke ); - WRITE_BYTE( ( pev->dmg - 50 ) * 0.80 ); // scale * 10 - WRITE_BYTE( 12 ); // framerate + WRITE_BYTE( (int)( ( pev->dmg - 50 ) * 0.80 ) ); // scale * 10 + WRITE_BYTE( 12 ); // framerate MESSAGE_END(); } UTIL_Remove( this ); @@ -165,7 +165,7 @@ void CGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T void CGrenade::PreDetonate( void ) { - CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, 400, 0.3 ); + CSoundEnt::InsertSound( bits_SOUND_DANGER, pev->origin, 400, 0.3 ); SetThink( &CGrenade::Detonate ); pev->nextthink = gpGlobals->time + 1; @@ -207,7 +207,7 @@ void CGrenade::DangerSoundThink( void ) return; } - CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, pev->velocity.Length(), 0.2 ); + CSoundEnt::InsertSound( bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, (int)pev->velocity.Length(), 0.2 ); pev->nextthink = gpGlobals->time + 0.2; if( pev->waterlevel != 0 ) @@ -253,7 +253,7 @@ void CGrenade::BounceTouch( CBaseEntity *pOther ) // go ahead and emit the danger sound. // register a radius louder than the explosion, so we make sure everyone gets out of the way - CSoundEnt::InsertSound( bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3 ); + CSoundEnt::InsertSound( bits_SOUND_DANGER, pev->origin, (int)( pev->dmg / 0.4 ), 0.3 ); m_fRegisteredSound = TRUE; } diff --git a/dlls/gman.cpp b/dlls/gman.cpp index bdfb60d4..377755f6 100644 --- a/dlls/gman.cpp +++ b/dlls/gman.cpp @@ -109,7 +109,7 @@ void CGMan::HandleAnimEvent( MonsterEvent_t *pEvent ) //========================================================= int CGMan::ISoundMask( void ) { - return NULL; + return 0; } //========================================================= @@ -149,7 +149,7 @@ void CGMan::StartTask( Task_t *pTask ) switch( pTask->iTask ) { case TASK_WAIT: - if( m_hPlayer == NULL ) + if( m_hPlayer == 0 ) { m_hPlayer = UTIL_FindEntityByClassname( NULL, "player" ); } @@ -164,7 +164,7 @@ void CGMan::RunTask( Task_t *pTask ) { case TASK_WAIT: // look at who I'm talking to - if( m_flTalkTime > gpGlobals->time && m_hTalkTarget != NULL ) + if( m_flTalkTime > gpGlobals->time && m_hTalkTarget != 0 ) { float yaw = VecToYaw( m_hTalkTarget->pev->origin - pev->origin ) - pev->angles.y; @@ -177,7 +177,7 @@ void CGMan::RunTask( Task_t *pTask ) SetBoneController( 0, yaw ); } // look at player, but only if playing a "safe" idle animation - else if( m_hPlayer != NULL && pev->sequence == 0 ) + else if( m_hPlayer != 0 && pev->sequence == 0 ) { float yaw = VecToYaw( m_hPlayer->pev->origin - pev->origin ) - pev->angles.y; diff --git a/dlls/h_battery.cpp b/dlls/h_battery.cpp index fdb7c645..976a5733 100644 --- a/dlls/h_battery.cpp +++ b/dlls/h_battery.cpp @@ -91,7 +91,7 @@ void CRecharge::Spawn() UTIL_SetOrigin( pev, pev->origin ); // set size and link into world UTIL_SetSize( pev, pev->mins, pev->maxs ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); - m_iJuice = gSkillData.suitchargerCapacity; + m_iJuice = (int)gSkillData.suitchargerCapacity; pev->frame = 0; } @@ -172,7 +172,7 @@ void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use void CRecharge::Recharge( void ) { - m_iJuice = gSkillData.suitchargerCapacity; + m_iJuice = (int)gSkillData.suitchargerCapacity; pev->frame = 0; SetThink( &CBaseEntity::SUB_DoNothing ); } @@ -185,7 +185,7 @@ void CRecharge::Off( void ) m_iOn = 0; - if( ( !m_iJuice ) && ( ( m_iReactivate = g_pGameRules->FlHEVChargerRechargeTime() ) > 0 ) ) + if( ( !m_iJuice ) && ( ( m_iReactivate = (int)g_pGameRules->FlHEVChargerRechargeTime() ) > 0 ) ) { pev->nextthink = pev->ltime + m_iReactivate; SetThink( &CRecharge::Recharge ); diff --git a/dlls/h_cine.cpp b/dlls/h_cine.cpp index fc503171..bb07e02c 100644 --- a/dlls/h_cine.cpp +++ b/dlls/h_cine.cpp @@ -31,7 +31,7 @@ class CLegacyCineMonster : public CBaseMonster { public: - void CineSpawn( char *szModel ); + void CineSpawn( const char *szModel ); void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); void EXPORT CineThink( void ); void Pain( void ); @@ -103,7 +103,7 @@ LINK_ENTITY_TO_CLASS( monster_cine3_barney, CCine3Barney ) // ********** Scientist SPAWN ********** // -void CLegacyCineMonster :: CineSpawn( char *szModel ) +void CLegacyCineMonster :: CineSpawn( const char *szModel ) { PRECACHE_MODEL(szModel); SET_MODEL(ENT(pev), szModel); diff --git a/dlls/h_cycler.cpp b/dlls/h_cycler.cpp index d685ac36..e920abfa 100644 --- a/dlls/h_cycler.cpp +++ b/dlls/h_cycler.cpp @@ -34,7 +34,7 @@ class CCycler : public CBaseMonster { public: - void GenericCyclerSpawn(char *szModel, Vector vecMin, Vector vecMax); + void GenericCyclerSpawn( const char *szModel, Vector vecMin, Vector vecMax ); virtual int ObjectCaps( void ) { return ( CBaseEntity::ObjectCaps() | FCAP_IMPULSE_USE ); } int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); void Spawn( void ); @@ -92,7 +92,7 @@ void CCyclerProbe::Spawn( void ) } // Cycler member functions -void CCycler::GenericCyclerSpawn( char *szModel, Vector vecMin, Vector vecMax ) +void CCycler::GenericCyclerSpawn( const char *szModel, Vector vecMin, Vector vecMax ) { if( !szModel || !*szModel ) { @@ -406,7 +406,7 @@ void CWreckage::Spawn( void ) } // pev->scale = 5.0; - m_flStartTime = gpGlobals->time; + m_flStartTime = (int)gpGlobals->time; } void CWreckage::Precache() diff --git a/dlls/hassassin.cpp b/dlls/hassassin.cpp index 5aac1e53..ff053595 100644 --- a/dlls/hassassin.cpp +++ b/dlls/hassassin.cpp @@ -185,7 +185,7 @@ void CHAssassin::SetYawSpeed( void ) //========================================================= void CHAssassin::Shoot( void ) { - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { return; } @@ -597,7 +597,7 @@ IMPLEMENT_CUSTOM_SCHEDULES( CHAssassin, CBaseMonster ) //========================================================= BOOL CHAssassin::CheckMeleeAttack1( float flDot, float flDist ) { - if( m_flNextJump < gpGlobals->time && ( flDist <= 128 || HasMemory( bits_MEMORY_BADJUMP ) ) && m_hEnemy != NULL ) + if( m_flNextJump < gpGlobals->time && ( flDist <= 128 || HasMemory( bits_MEMORY_BADJUMP ) ) && m_hEnemy != 0 ) { TraceResult tr; @@ -687,7 +687,7 @@ void CHAssassin::RunAI( void ) // always visible if moving // always visible is not on hard - if( g_iSkillLevel != SKILL_HARD || m_hEnemy == NULL || pev->deadflag != DEAD_NO || m_Activity == ACT_RUN || m_Activity == ACT_WALK || !( pev->flags & FL_ONGROUND ) ) + if( g_iSkillLevel != SKILL_HARD || m_hEnemy == 0 || pev->deadflag != DEAD_NO || m_Activity == ACT_RUN || m_Activity == ACT_WALK || !( pev->flags & FL_ONGROUND ) ) m_iTargetRanderamt = 255; else m_iTargetRanderamt = 20; diff --git a/dlls/headcrab.cpp b/dlls/headcrab.cpp index d84a692e..60e03c10 100644 --- a/dlls/headcrab.cpp +++ b/dlls/headcrab.cpp @@ -226,7 +226,7 @@ void CHeadCrab::HandleAnimEvent( MonsterEvent_t *pEvent ) UTIL_MakeVectors( pev->angles ); Vector vecJumpDir; - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { float gravity = g_psv_gravity->value; if( gravity <= 1 ) @@ -538,7 +538,7 @@ Schedule_t *CBabyCrab::GetScheduleOfType( int Type ) switch( Type ) { case SCHED_FAIL: // If you fail, try to jump! - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) return slHCRangeAttack1Fast; break; case SCHED_RANGE_ATTACK1: diff --git a/dlls/healthkit.cpp b/dlls/healthkit.cpp index e1b22467..99d53d35 100644 --- a/dlls/healthkit.cpp +++ b/dlls/healthkit.cpp @@ -159,7 +159,7 @@ void CWallHealth::Spawn() UTIL_SetOrigin( pev, pev->origin ); // set size and link into world UTIL_SetSize( pev, pev->mins, pev->maxs ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); - m_iJuice = gSkillData.healthchargerCapacity; + m_iJuice = (int)gSkillData.healthchargerCapacity; pev->frame = 0; } @@ -230,7 +230,7 @@ void CWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE u void CWallHealth::Recharge( void ) { EMIT_SOUND( ENT( pev ), CHAN_ITEM, "items/medshot4.wav", 1.0, ATTN_NORM ); - m_iJuice = gSkillData.healthchargerCapacity; + m_iJuice = (int)gSkillData.healthchargerCapacity; pev->frame = 0; SetThink( &CBaseEntity::SUB_DoNothing ); } @@ -243,7 +243,7 @@ void CWallHealth::Off( void ) m_iOn = 0; - if( ( !m_iJuice ) && ( ( m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime() ) > 0 ) ) + if( ( !m_iJuice ) && ( ( m_iReactivate = (int)g_pGameRules->FlHealthChargerRechargeTime() ) > 0 ) ) { pev->nextthink = pev->ltime + m_iReactivate; SetThink( &CWallHealth::Recharge ); diff --git a/dlls/hgrunt.cpp b/dlls/hgrunt.cpp index 7b0eaa2c..4cb85c2c 100644 --- a/dlls/hgrunt.cpp +++ b/dlls/hgrunt.cpp @@ -217,7 +217,7 @@ const char *CHGrunt::pGruntSentences[] = "HG_TAUNT", // say rude things }; -enum +typedef enum { HGRUNT_SENT_NONE = -1, HGRUNT_SENT_GREN = 0, @@ -366,7 +366,7 @@ void CHGrunt::JustSpoke( void ) //========================================================= void CHGrunt::PrescheduleThink( void ) { - if( InSquad() && m_hEnemy != NULL ) + if( InSquad() && m_hEnemy != 0 ) { if( HasConditions( bits_COND_SEE_ENEMY ) ) { @@ -413,9 +413,9 @@ BOOL CHGrunt::FCanCheckAttacks( void ) //========================================================= BOOL CHGrunt::CheckMeleeAttack1( float flDot, float flDist ) { - CBaseMonster *pEnemy; + CBaseMonster *pEnemy = 0; - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { pEnemy = m_hEnemy->MyMonsterPointer(); @@ -787,7 +787,7 @@ Vector CHGrunt::GetGunPosition() //========================================================= void CHGrunt::Shoot( void ) { - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { return; } @@ -814,7 +814,7 @@ void CHGrunt::Shoot( void ) //========================================================= void CHGrunt::Shotgun( void ) { - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { return; } @@ -1834,7 +1834,7 @@ IMPLEMENT_CUSTOM_SCHEDULES( CHGrunt, CSquadMonster ) void CHGrunt::SetActivity( Activity NewActivity ) { int iSequence = ACTIVITY_NOT_AVAILABLE; - void *pmodel = GET_MODEL_PTR( ENT( pev ) ); + //void *pmodel = GET_MODEL_PTR( ENT( pev ) ); switch( NewActivity ) { @@ -2032,10 +2032,10 @@ Schedule_t *CHGrunt::GetSchedule( void ) // before he starts pluggin away. if( FOkToSpeak() )// && RANDOM_LONG( 0, 1 ) ) { - if( ( m_hEnemy != NULL ) && m_hEnemy->IsPlayer() ) + if( ( m_hEnemy != 0 ) && m_hEnemy->IsPlayer() ) // player SENTENCEG_PlayRndSz( ENT( pev ), "HG_ALERT", HGRUNT_SENTENCE_VOLUME, GRUNT_ATTN, 0, m_voicePitch ); - else if( ( m_hEnemy != NULL ) && + else if( ( m_hEnemy != 0 ) && ( m_hEnemy->Classify() != CLASS_PLAYER_ALLY ) && ( m_hEnemy->Classify() != CLASS_HUMAN_PASSIVE ) && ( m_hEnemy->Classify() != CLASS_MACHINE ) ) @@ -2072,7 +2072,7 @@ Schedule_t *CHGrunt::GetSchedule( void ) // 10% chance of flinch. int iPercent = RANDOM_LONG( 0, 99 ); - if( iPercent <= 90 && m_hEnemy != NULL ) + if( iPercent <= 90 && m_hEnemy != 0 ) { // only try to take cover if we actually have an enemy! @@ -2308,7 +2308,7 @@ Schedule_t *CHGrunt::GetScheduleOfType( int Type ) } case SCHED_FAIL: { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { // grunt has an enemy, so pick a different default fail schedule most likely to help recover. return &slGruntCombatFail[0]; @@ -2408,10 +2408,10 @@ public: void KeyValue( KeyValueData *pkvd ); int m_iPose;// which sequence to display -- temporary, don't need to save - static char *m_szPoses[3]; + static const char *m_szPoses[3]; }; -char *CDeadHGrunt::m_szPoses[] = { "deadstomach", "deadside", "deadsitting" }; +const char *CDeadHGrunt::m_szPoses[] = { "deadstomach", "deadside", "deadsitting" }; void CDeadHGrunt::KeyValue( KeyValueData *pkvd ) { diff --git a/dlls/hornet.cpp b/dlls/hornet.cpp index 1e7025a0..d968b79b 100644 --- a/dlls/hornet.cpp +++ b/dlls/hornet.cpp @@ -258,14 +258,14 @@ void CHornet::TrackTarget( void ) } // UNDONE: The player pointer should come back after returning from another level - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { // enemy is dead. Look( 512 ); m_hEnemy = BestVisibleEnemy(); } - if( m_hEnemy != NULL && FVisible( m_hEnemy ) ) + if( m_hEnemy != 0 && FVisible( m_hEnemy ) ) { m_vecEnemyLKP = m_hEnemy->BodyTarget( pev->origin ); } @@ -335,7 +335,7 @@ void CHornet::TrackTarget( void ) // if hornet is close to the enemy, jet in a straight line for a half second. // (only in the single player game) - if( m_hEnemy != NULL && !g_pGameRules->IsMultiplayer() ) + if( m_hEnemy != 0 && !g_pGameRules->IsMultiplayer() ) { if( flDelta >= 0.4 && ( pev->origin - m_vecEnemyLKP ).Length() <= 300 ) { diff --git a/dlls/houndeye.cpp b/dlls/houndeye.cpp index f35b0740..cedee258 100644 --- a/dlls/houndeye.cpp +++ b/dlls/houndeye.cpp @@ -137,7 +137,7 @@ int CHoundeye::Classify( void ) //========================================================= BOOL CHoundeye::FValidateHintType( short sHint ) { - int i; + size_t i; static short sHoundHints[] = { diff --git a/dlls/ichthyosaur.cpp b/dlls/ichthyosaur.cpp index cbc86d50..53f57a27 100644 --- a/dlls/ichthyosaur.cpp +++ b/dlls/ichthyosaur.cpp @@ -416,7 +416,7 @@ void CIchthyosaur::HandleAnimEvent( MonsterEvent_t *pEvent ) case ICHTHYOSAUR_AE_SHAKE_RIGHT: case ICHTHYOSAUR_AE_SHAKE_LEFT: { - if( m_hEnemy != NULL && FVisible( m_hEnemy ) ) + if( m_hEnemy != 0 && FVisible( m_hEnemy ) ) { CBaseEntity *pHurt = m_hEnemy; @@ -622,7 +622,7 @@ void CIchthyosaur::RunTask( Task_t *pTask ) switch( pTask->iTask ) { case TASK_ICHTHYOSAUR_CIRCLE_ENEMY: - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { TaskComplete(); } @@ -864,7 +864,7 @@ void CIchthyosaur::Stop( void ) void CIchthyosaur::Swim() { - int retValue = 0; + //int retValue = 0; Vector start = pev->origin; @@ -1072,7 +1072,7 @@ Vector CIchthyosaur::DoProbe( const Vector &Probe ) } } - if( bBumpedSomething && ( m_hEnemy == NULL || tr.pHit != m_hEnemy->edict() ) ) + if( bBumpedSomething && ( m_hEnemy == 0 || tr.pHit != m_hEnemy->edict() ) ) { Vector ProbeDir = Probe - pev->origin; diff --git a/dlls/islave.cpp b/dlls/islave.cpp index cfb1df1b..3b4343d3 100644 --- a/dlls/islave.cpp +++ b/dlls/islave.cpp @@ -51,7 +51,7 @@ public: void HandleAnimEvent( MonsterEvent_t *pEvent ); BOOL CheckRangeAttack1( float flDot, float flDist ); BOOL CheckRangeAttack2( float flDot, float flDist ); - void CallForHelp( char *szClassname, float flDist, EHANDLE hEnemy, Vector &vecLocation ); + void CallForHelp( const char *szClassname, float flDist, EHANDLE hEnemy, Vector &vecLocation ); void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); @@ -155,7 +155,7 @@ int CISlave::IRelationship( CBaseEntity *pTarget ) return CBaseMonster::IRelationship( pTarget ); } -void CISlave::CallForHelp( char *szClassname, float flDist, EHANDLE hEnemy, Vector &vecLocation ) +void CISlave::CallForHelp( const char *szClassname, float flDist, EHANDLE hEnemy, Vector &vecLocation ) { // ALERT( at_aiconsole, "help " ); @@ -185,7 +185,7 @@ void CISlave::CallForHelp( char *szClassname, float flDist, EHANDLE hEnemy, Vect //========================================================= void CISlave::AlertSound( void ) { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { SENTENCEG_PlayRndSz( ENT( pev ), "SLV_ALERT", 0.85, ATTN_NORM, 0, m_voicePitch ); @@ -365,7 +365,7 @@ void CISlave::HandleAnimEvent( MonsterEvent_t *pEvent ) WRITE_BYTE( 0 ); // decay * 0.1 MESSAGE_END(); } - if( m_hDead != NULL ) + if( m_hDead != 0 ) { WackBeam( -1, m_hDead ); WackBeam( 1, m_hDead ); @@ -385,7 +385,7 @@ void CISlave::HandleAnimEvent( MonsterEvent_t *pEvent ) { ClearBeams(); - if( m_hDead != NULL ) + if( m_hDead != 0 ) { Vector vecDest = m_hDead->pev->origin + Vector( 0, 0, 38 ); TraceResult trace; @@ -394,7 +394,7 @@ void CISlave::HandleAnimEvent( MonsterEvent_t *pEvent ) if( !trace.fStartSolid ) { CBaseEntity *pNew = Create( "monster_alien_slave", m_hDead->pev->origin, m_hDead->pev->angles ); - CBaseMonster *pNewMonster = pNew->MyMonsterPointer( ); + //CBaseMonster *pNewMonster = pNew->MyMonsterPointer(); pNew->pev->spawnflags |= 1; WackBeam( -1, pNew ); WackBeam( 1, pNew ); @@ -484,7 +484,7 @@ BOOL CISlave::CheckRangeAttack2( float flDot, float flDist ) } } } - if( m_hDead != NULL ) + if( m_hDead != 0 ) return TRUE; else return FALSE; @@ -530,7 +530,7 @@ void CISlave::Spawn() //========================================================= void CISlave::Precache() { - int i; + size_t i; PRECACHE_MODEL( "models/islave.mdl" ); PRECACHE_MODEL( "sprites/lgtning.spr" ); @@ -756,8 +756,8 @@ void CISlave::BeamGlow() //========================================================= void CISlave::WackBeam( int side, CBaseEntity *pEntity ) { - Vector vecDest; - float flDist = 1.0; + //Vector vecDest; + //float flDist = 1.0; if( m_iBeams >= ISLAVE_MAX_BEAMS ) return; diff --git a/dlls/leech.cpp b/dlls/leech.cpp index ea524aaa..dccffcf4 100644 --- a/dlls/leech.cpp +++ b/dlls/leech.cpp @@ -271,7 +271,7 @@ void CLeech::AlertSound( void ) void CLeech::Precache( void ) { - int i; + size_t i; //PRECACHE_MODEL( "models/icky.mdl" ); PRECACHE_MODEL( "models/leech.mdl" ); diff --git a/dlls/lights.cpp b/dlls/lights.cpp index 2a8b0683..e6b03125 100644 --- a/dlls/lights.cpp +++ b/dlls/lights.cpp @@ -99,7 +99,7 @@ void CLight::Spawn( void ) if( FBitSet( pev->spawnflags, SF_LIGHT_START_OFF ) ) LIGHT_STYLE( m_iStyle, "a" ); else if( m_iszPattern ) - LIGHT_STYLE( m_iStyle, (char *)STRING( m_iszPattern ) ); + LIGHT_STYLE( m_iStyle, STRING( m_iszPattern ) ); else LIGHT_STYLE( m_iStyle, "m" ); } @@ -115,7 +115,7 @@ void CLight::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useTyp if( FBitSet( pev->spawnflags, SF_LIGHT_START_OFF ) ) { if( m_iszPattern ) - LIGHT_STYLE( m_iStyle, (char *)STRING( m_iszPattern ) ); + LIGHT_STYLE( m_iStyle, STRING( m_iszPattern ) ); else LIGHT_STYLE( m_iStyle, "m" ); ClearBits( pev->spawnflags, SF_LIGHT_START_OFF ); @@ -155,15 +155,16 @@ void CEnvLight::KeyValue( KeyValueData* pkvd ) } else if( j == 4 ) { - r = r * ( v / 255.0 ); - g = g * ( v / 255.0 ); - b = b * ( v / 255.0 ); + v /= 255; + r *= v; + g *= v; + b *= v; } // simulate qrad direct, ambient,and gamma adjustments, as well as engine scaling - r = pow( r / 114.0, 0.6 ) * 264; - g = pow( g / 114.0, 0.6 ) * 264; - b = pow( b / 114.0, 0.6 ) * 264; + r = (int)( pow( r / 114.0, 0.6 ) * 264.0 ); + g = (int)( pow( g / 114.0, 0.6 ) * 264.0 ); + b = (int)( pow( b / 114.0, 0.6 ) * 264.0 ); pkvd->fHandled = TRUE; sprintf( szColor, "%d", r ); diff --git a/dlls/maprules.cpp b/dlls/maprules.cpp index 3eea7486..2230acac 100644 --- a/dlls/maprules.cpp +++ b/dlls/maprules.cpp @@ -64,9 +64,9 @@ void CRuleEntity::Spawn( void ) void CRuleEntity::KeyValue( KeyValueData *pkvd ) { - if (FStrEq(pkvd->szKeyName, "master")) + if( FStrEq(pkvd->szKeyName, "master" ) ) { - SetMaster( ALLOC_STRING(pkvd->szValue) ); + SetMaster( ALLOC_STRING( pkvd->szValue ) ); pkvd->fHandled = TRUE; } else @@ -75,9 +75,9 @@ void CRuleEntity::KeyValue( KeyValueData *pkvd ) BOOL CRuleEntity::CanFireForActivator( CBaseEntity *pActivator ) { - if ( m_iszMaster ) + if( m_iszMaster ) { - if ( UTIL_IsMasterTriggered( m_iszMaster, pActivator ) ) + if( UTIL_IsMasterTriggered( m_iszMaster, pActivator ) ) return TRUE; else return FALSE; @@ -135,7 +135,7 @@ public: void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); void KeyValue( KeyValueData *pkvd ); - inline int Points( void ) { return pev->frags; } + inline int Points( void ) { return (int)pev->frags; } inline BOOL AllowNegativeScore( void ) { return pev->spawnflags & SF_SCORE_NEGATIVE; } inline BOOL AwardToTeam( void ) { return pev->spawnflags & SF_SCORE_TEAM; } @@ -643,8 +643,8 @@ public: inline void CountUp( void ) { pev->frags++; } inline void CountDown( void ) { pev->frags--; } inline void ResetCount( void ) { pev->frags = pev->dmg; } - inline int CountValue( void ) { return pev->frags; } - inline int LimitValue( void ) { return pev->health; } + inline int CountValue( void ) { return (int)pev->frags; } + inline int LimitValue( void ) { return (int)pev->health; } inline BOOL HitLimit( void ) { return CountValue() == LimitValue(); } diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index d034abd6..cfe4c561 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -133,7 +133,7 @@ int CBaseMonster::Restore( CRestore &restore ) m_Activity = ACT_RESET; // If we don't have an enemy, clear conditions like see enemy, etc. - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) m_afConditions = 0; return status; @@ -672,7 +672,7 @@ BOOL CBaseMonster::FRefreshRoute( void ) returnCode = BuildRoute( m_vecMoveGoal, bits_MF_TO_LOCATION, NULL ); break; case MOVEGOAL_TARGETENT: - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) { returnCode = BuildRoute( m_hTargetEnt->pev->origin, bits_MF_TO_TARGETENT, m_hTargetEnt ); } @@ -954,7 +954,7 @@ BOOL CBaseMonster::CheckRangeAttack2( float flDot, float flDist ) BOOL CBaseMonster::CheckMeleeAttack1( float flDot, float flDist ) { // Decent fix to keep folks from kicking/punching hornets and snarks is to check the onground flag(sjb) - if( flDist <= 64 && flDot >= 0.7 && m_hEnemy != NULL && FBitSet( m_hEnemy->pev->flags, FL_ONGROUND ) ) + if( flDist <= 64 && flDot >= 0.7 && m_hEnemy != 0 && FBitSet( m_hEnemy->pev->flags, FL_ONGROUND ) ) { return TRUE; } @@ -1165,7 +1165,7 @@ void CBaseMonster::PushEnemy( CBaseEntity *pEnemy, Vector &vecLastKnownPos ) { if( m_hOldEnemy[i] == pEnemy ) return; - if( m_hOldEnemy[i] == NULL ) // someone died, reuse their slot + if( m_hOldEnemy[i] == 0 ) // someone died, reuse their slot break; } if( i >= MAX_OLD_ENEMIES ) @@ -1183,7 +1183,7 @@ BOOL CBaseMonster::PopEnemy() // UNDONE: blah, this is bad, we should use a stack but I'm too lazy to code one. for( int i = MAX_OLD_ENEMIES - 1; i >= 0; i-- ) { - if( m_hOldEnemy[i] != NULL ) + if( m_hOldEnemy[i] != 0 ) { if( m_hOldEnemy[i]->IsAlive()) // cheat and know when they die { @@ -1240,7 +1240,7 @@ void CBaseMonster::SetActivity( Activity NewActivity ) //========================================================= // SetSequenceByName //========================================================= -void CBaseMonster::SetSequenceByName( char *szSequence ) +void CBaseMonster::SetSequenceByName( const char *szSequence ) { int iSequence; @@ -2863,7 +2863,7 @@ void CBaseMonster::ReportAIState( void ) else ALERT( level, "No Schedule, " ); - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) ALERT( level, "\nEnemy is %s", STRING( m_hEnemy->pev->classname ) ); else ALERT( level, "No enemy" ); @@ -2950,7 +2950,7 @@ BOOL CBaseMonster::FCheckAITrigger( void ) switch( m_iTriggerCondition ) { case AITRIGGER_SEEPLAYER_ANGRY_AT_PLAYER: - if( m_hEnemy != NULL && m_hEnemy->IsPlayer() && HasConditions( bits_COND_SEE_ENEMY ) ) + if( m_hEnemy != 0 && m_hEnemy->IsPlayer() && HasConditions( bits_COND_SEE_ENEMY ) ) { fFireTarget = TRUE; } @@ -3321,7 +3321,7 @@ BOOL CBaseMonster::GetEnemy( void ) } // remember old enemies - if( m_hEnemy == NULL && PopEnemy() ) + if( m_hEnemy == 0 && PopEnemy() ) { if( m_pSchedule ) { @@ -3332,7 +3332,7 @@ BOOL CBaseMonster::GetEnemy( void ) } } - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { // monster has an enemy. return TRUE; @@ -3344,7 +3344,7 @@ BOOL CBaseMonster::GetEnemy( void ) //========================================================= // DropItem - dead monster drops named item //========================================================= -CBaseEntity *CBaseMonster::DropItem( char *pszItemName, const Vector &vecPos, const Vector &vecAng ) +CBaseEntity *CBaseMonster::DropItem( const char *pszItemName, const Vector &vecPos, const Vector &vecAng ) { if( !pszItemName ) { diff --git a/dlls/monsterstate.cpp b/dlls/monsterstate.cpp index f29664dc..cec29b79 100644 --- a/dlls/monsterstate.cpp +++ b/dlls/monsterstate.cpp @@ -42,7 +42,7 @@ void CBaseMonster::SetState( MONSTERSTATE State ) // Drop enemy pointers when going to idle case MONSTERSTATE_IDLE: - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { m_hEnemy = NULL;// not allowed to have an enemy anymore. ALERT( at_aiconsole, "Stripped\n" ); @@ -92,7 +92,7 @@ void CBaseMonster::RunAI( void ) } // do these calculations if monster has an enemy. - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { CheckEnemy( m_hEnemy ); } @@ -198,7 +198,7 @@ MONSTERSTATE CBaseMonster::GetIdealState( void ) COMBAT goes to ALERT upon death of enemy */ { - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { m_IdealMonsterState = MONSTERSTATE_ALERT; // pev->effects = EF_BRIGHTFIELD; diff --git a/dlls/mpstubb.cpp b/dlls/mpstubb.cpp index 703a4dba..12b3a82f 100644 --- a/dlls/mpstubb.cpp +++ b/dlls/mpstubb.cpp @@ -230,7 +230,7 @@ CBaseEntity *CBaseMonster::BestVisibleEnemy( void ) // currently think is the best visible enemy. No need to do // a distance check, just get mad at this one for now. iBestRelationship = IRelationship( pNextEnt ); - iNearest = ( pNextEnt->pev->origin - pev->origin ).Length(); + (int)iNearest = ( pNextEnt->pev->origin - pev->origin ).Length(); pReturn = pNextEnt; } else if( IRelationship( pNextEnt ) == iBestRelationship ) @@ -238,7 +238,7 @@ CBaseEntity *CBaseMonster::BestVisibleEnemy( void ) // this entity is disliked just as much as the entity that // we currently think is the best visible enemy, so we only // get mad at it if it is closer. - iDist = ( pNextEnt->pev->origin - pev->origin ).Length(); + (int)iDist = ( pNextEnt->pev->origin - pev->origin ).Length(); if( iDist <= iNearest ) { diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index ebef51de..9da8d0b4 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -256,7 +256,7 @@ void CHalfLifeMultiplay::Think( void ) if( pPlayer ) { - remain = flFragLimit - pPlayer->pev->frags; + remain = (int)( flFragLimit - pPlayer->pev->frags ); if( remain < bestfrags ) { bestfrags = remain; @@ -300,7 +300,7 @@ BOOL CHalfLifeMultiplay::IsDeathmatch( void ) //========================================================= BOOL CHalfLifeMultiplay::IsCoOp( void ) { - return gpGlobals->coop; + return gpGlobals->coop ? TRUE : FALSE; } //========================================================= @@ -467,7 +467,7 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pl ) { MESSAGE_BEGIN( MSG_ONE, gmsgScoreInfo, NULL, pl->edict() ); WRITE_BYTE( i ); // client number - WRITE_SHORT( plr->pev->frags ); + WRITE_SHORT( (int)plr->pev->frags ); WRITE_SHORT( plr->m_iDeaths ); WRITE_SHORT( 0 ); WRITE_SHORT( GetTeamIndex( plr->m_szTeamName ) + 1 ); @@ -652,7 +652,7 @@ void CHalfLifeMultiplay::PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, // killed scores MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); WRITE_BYTE( ENTINDEX(pVictim->edict()) ); - WRITE_SHORT( pVictim->pev->frags ); + WRITE_SHORT( (int)pVictim->pev->frags ); WRITE_SHORT( pVictim->m_iDeaths ); WRITE_SHORT( 0 ); WRITE_SHORT( GetTeamIndex( pVictim->m_szTeamName ) + 1 ); @@ -666,7 +666,7 @@ void CHalfLifeMultiplay::PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); WRITE_BYTE( ENTINDEX( PK->edict() ) ); - WRITE_SHORT( PK->pev->frags ); + WRITE_SHORT( (int)PK->pev->frags ); WRITE_SHORT( PK->m_iDeaths ); WRITE_SHORT( 0 ); WRITE_SHORT( GetTeamIndex( PK->m_szTeamName ) + 1 ); @@ -689,14 +689,14 @@ void CHalfLifeMultiplay::PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ) { // Work out what killed the player, and send a message to all clients about it - CBaseEntity *Killer = CBaseEntity::Instance( pKiller ); + CBaseEntity::Instance( pKiller ); const char *killer_weapon_name = "world"; // by default, the player is killed by the world int killer_index = 0; // Hack to fix name change - char *tau = "tau_cannon"; - char *gluon = "gluon gun"; + const char *tau = "tau_cannon"; + const char *gluon = "gluon gun"; if( pKiller->flags & FL_CLIENT ) { diff --git a/dlls/nihilanth.cpp b/dlls/nihilanth.cpp index ba1c6192..479a2b34 100644 --- a/dlls/nihilanth.cpp +++ b/dlls/nihilanth.cpp @@ -587,7 +587,7 @@ void CNihilanth::ShootBalls( void ) while( m_flShootTime < m_flShootEnd && m_flShootTime < gpGlobals->time ) { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { Vector vecSrc, vecDir; CNihilanthHVR *pEntity; @@ -742,7 +742,7 @@ void CNihilanth::NextActivity() float flDist = ( m_posDesired - pev->origin ).Length(); float flDot = DotProduct( m_vecDesired, gpGlobals->v_forward ); - if( m_hRecharger != NULL ) + if( m_hRecharger != 0 ) { // at we at power up yet? if( flDist < 128.0 ) @@ -767,23 +767,23 @@ void CNihilanth::NextActivity() return; } - if( m_hEnemy != NULL && !m_hEnemy->IsAlive() ) + if( m_hEnemy != 0 && !m_hEnemy->IsAlive() ) { - m_hEnemy = NULL; + m_hEnemy = 0; } if( m_flLastSeen + 15 < gpGlobals->time ) { - m_hEnemy = NULL; + m_hEnemy = 0; } - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { Look( 4096 ); m_hEnemy = BestVisibleEnemy(); } - if( m_hEnemy != NULL && m_irritation != 0 ) + if( m_hEnemy != 0 && m_irritation != 0 ) { if( m_flLastSeen + 5 > gpGlobals->time && flDist < 256 && flDot > 0 ) { @@ -860,7 +860,7 @@ void CNihilanth::HuntThink( void ) } // look for current enemy - if( m_hEnemy != NULL && m_hRecharger == NULL ) + if( m_hEnemy != 0 && m_hRecharger == NULL ) { if( FVisible( m_hEnemy ) ) { @@ -928,7 +928,7 @@ void CNihilanth::Flight( void ) if( flDir < 0 ) flSpeed = -flSpeed; - float flDist = DotProduct( m_posDesired - vecEst, gpGlobals->v_forward ); + //float flDist = DotProduct( m_posDesired - vecEst, gpGlobals->v_forward ); // sideways drag m_velocity.x = m_velocity.x * ( 1.0 - fabs( gpGlobals->v_right.x ) * 0.05 ); @@ -959,7 +959,7 @@ BOOL CNihilanth::AbsorbSphere( void ) { for( int i = 0; i < N_SPHERES; i++ ) { - if( m_hSphere[i] != NULL ) + if( m_hSphere[i] != 0 ) { CNihilanthHVR *pSphere = (CNihilanthHVR *)( (CBaseEntity *)m_hSphere[i] ); pSphere->AbsorbInit(); @@ -978,7 +978,7 @@ BOOL CNihilanth::EmitSphere( void ) for( int i = 0; i < N_SPHERES; i++ ) { - if( m_hSphere[i] != NULL ) + if( m_hSphere[i] != 0 ) { m_iActiveSpheres++; } @@ -1007,10 +1007,10 @@ void CNihilanth::TargetSphere( USE_TYPE useType, float value ) for( i = 0; i < N_SPHERES; i++ ) { - if( m_hSphere[i] != NULL ) + if( m_hSphere[i] != 0 ) { pSphere = m_hSphere[i]->MyMonsterPointer(); - if( pSphere->m_hEnemy == NULL ) + if( pSphere->m_hEnemy == 0 ) break; } } @@ -1141,7 +1141,7 @@ void CNihilanth::HandleAnimEvent( MonsterEvent_t *pEvent ) case 4: // get a sphere { - if( m_hRecharger != NULL ) + if( m_hRecharger != 0 ) { if( !EmitSphere() ) { @@ -1340,7 +1340,7 @@ void CNihilanthHVR::HoverThink( void ) { pev->nextthink = gpGlobals->time + 0.1; - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) { CircleTarget( m_hTargetEnt->pev->origin + Vector( 0, 0, 16 * N_SCALE ) ); } @@ -1424,7 +1424,7 @@ void CNihilanthHVR::ZapThink( void ) pev->nextthink = gpGlobals->time + 0.05; // check world boundaries - if( m_hEnemy == NULL || pev->origin.x < -4096 || pev->origin.x > 4096 || pev->origin.y < -4096 || pev->origin.y > 4096 || pev->origin.z < -4096 || pev->origin.z > 4096 ) + if( m_hEnemy == 0 || pev->origin.x < -4096 || pev->origin.x > 4096 || pev->origin.y < -4096 || pev->origin.y > 4096 || pev->origin.z < -4096 || pev->origin.z > 4096 ) { SetTouch( NULL ); UTIL_Remove( this ); @@ -1561,7 +1561,7 @@ void CNihilanthHVR::TeleportThink( void ) pev->nextthink = gpGlobals->time + 0.1; // check world boundaries - if( m_hEnemy == NULL || !m_hEnemy->IsAlive() || pev->origin.x < -4096 || pev->origin.x > 4096 || pev->origin.y < -4096 || pev->origin.y > 4096 || pev->origin.z < -4096 || pev->origin.z > 4096 ) + if( m_hEnemy == 0 || !m_hEnemy->IsAlive() || pev->origin.x < -4096 || pev->origin.x > 4096 || pev->origin.y < -4096 || pev->origin.y > 4096 || pev->origin.z < -4096 || pev->origin.z > 4096 ) { STOP_SOUND( edict(), CHAN_WEAPON, "x/x_teleattack1.wav" ); UTIL_Remove( this ); @@ -1573,10 +1573,10 @@ void CNihilanthHVR::TeleportThink( void ) STOP_SOUND( edict(), CHAN_WEAPON, "x/x_teleattack1.wav" ); UTIL_Remove( this ); - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) m_hTargetEnt->Use( m_hEnemy, m_hEnemy, USE_ON, 1.0 ); - if( m_hTouch != NULL && m_hEnemy != NULL ) + if( m_hTouch != 0 && m_hEnemy != NULL ) m_hTouch->Touch( m_hEnemy ); } else @@ -1630,10 +1630,10 @@ void CNihilanthHVR::TeleportTouch( CBaseEntity *pOther ) if( pOther == pEnemy ) { - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) m_hTargetEnt->Use( pEnemy, pEnemy, USE_ON, 1.0 ); - if( m_hTouch != NULL && pEnemy != NULL ) + if( m_hTouch != 0 && pEnemy != NULL ) m_hTouch->Touch( pEnemy ); } else @@ -1656,7 +1656,7 @@ void CNihilanthHVR::DissipateThink( void ) pev->renderamt -= 2; pev->scale += 0.1; - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) { CircleTarget( m_hTargetEnt->pev->origin + Vector( 0, 0, 4096 ) ); } diff --git a/dlls/nodes.cpp b/dlls/nodes.cpp index a97b6a80..68a1c267 100644 --- a/dlls/nodes.cpp +++ b/dlls/nodes.cpp @@ -214,7 +214,7 @@ entvars_t *CGraph::LinkEntForLink( CLink *pLink, CNode *pNode ) //========================================================= int CGraph::HandleLinkEnt( int iNode, entvars_t *pevLinkEnt, int afCapMask, NODEQUERY queryType ) { - edict_t *pentWorld; + //edict_t *pentWorld; CBaseEntity *pDoor; TraceResult tr; @@ -230,7 +230,7 @@ int CGraph::HandleLinkEnt( int iNode, entvars_t *pevLinkEnt, int afCapMask, NODE ALERT( at_aiconsole, "dead path ent!\n" ); return TRUE; } - pentWorld = NULL; + //pentWorld = NULL; // func_door if( FClassnameIs( pevLinkEnt, "func_door" ) || FClassnameIs( pevLinkEnt, "func_door_rotating" ) ) @@ -586,7 +586,7 @@ int CGraph::FindShortestPath( int *piPath, int iStart, int iDest, int iHull, int int iVisitNode; int iCurrentNode; int iNumPathNodes; - int iHullMask; + int iHullMask = 0; if( !m_fGraphPresent || !m_fGraphPointersSet ) { @@ -1665,10 +1665,10 @@ void CTestHull::BuildNodeGraph( void ) int iBadNode;// this is the node that caused graph generation to fail - int cMaxInitialLinks = 0; - int cMaxValidLinks = 0; + //int cMaxInitialLinks = 0; + //int cMaxValidLinks = 0; - int iPoolIndex = 0; + //int iPoolIndex = 0; int cPoolLinks;// number of links in the pool. Vector vecDirToCheckNode; @@ -2058,11 +2058,16 @@ void CTestHull::BuildNodeGraph( void ) fprintf( file, "\nAll Connections are Paired!\n" ); } +#ifdef _MSC_VER +#define SIZET_FMT "%Iu" +#else +#define SIZET_FMT "%zu" +#endif fprintf( file, "-------------------------------------------------------------------------------\n" ); fprintf( file, "\n\n-------------------------------------------------------------------------------\n" ); fprintf( file, "Total Number of Connections in Pool: %d\n", cPoolLinks ); fprintf( file, "-------------------------------------------------------------------------------\n" ); - fprintf( file, "Connection Pool: %d bytes\n", sizeof(CLink) * cPoolLinks ); + fprintf( file, "Connection Pool: " SIZET_FMT " bytes\n", sizeof(CLink) * cPoolLinks ); fprintf( file, "-------------------------------------------------------------------------------\n" ); ALERT( at_aiconsole, "%d Nodes, %d Connections\n", WorldGraph.m_cNodes, cPoolLinks ); diff --git a/dlls/nodes.h b/dlls/nodes.h index 27b890ed..2b582a6f 100644 --- a/dlls/nodes.h +++ b/dlls/nodes.h @@ -15,7 +15,8 @@ //========================================================= // nodes.h //========================================================= - +#ifndef NODES_H +#define NODES_H //========================================================= // DEFINE //========================================================= @@ -370,3 +371,4 @@ enum }; extern CGraph WorldGraph; +#endif // NODES_H diff --git a/dlls/observer.cpp b/dlls/observer.cpp index 0eda7490..f3fc54a0 100644 --- a/dlls/observer.cpp +++ b/dlls/observer.cpp @@ -35,7 +35,7 @@ void CBasePlayer::Observer_FindNextPlayer( bool bReverse ) else iStart = ENTINDEX( edict() ); int iCurrent = iStart; - m_hObserverTarget = NULL; + m_hObserverTarget = 0; int iDir = bReverse ? -1 : 1; do @@ -125,11 +125,11 @@ void CBasePlayer::Observer_CheckTarget() return; // try to find a traget if we have no current one - if( m_hObserverTarget == NULL ) + if( m_hObserverTarget == 0 ) { Observer_FindNextPlayer( false ); - if( m_hObserverTarget == NULL ) + if( m_hObserverTarget == 0 ) { // no target found at all @@ -166,7 +166,7 @@ void CBasePlayer::Observer_CheckTarget() void CBasePlayer::Observer_CheckProperties() { // try to find a traget if we have no current one - if( pev->iuser1 == OBS_IN_EYE && m_hObserverTarget != NULL ) + if( pev->iuser1 == OBS_IN_EYE && m_hObserverTarget != 0 ) { CBasePlayer* target = (CBasePlayer*)( UTIL_PlayerByIndex( ENTINDEX( m_hObserverTarget->edict() ) ) ); @@ -222,26 +222,26 @@ void CBasePlayer::Observer_SetMode( int iMode ) if( iMode < OBS_CHASE_LOCKED || iMode > OBS_MAP_CHASE ) iMode = OBS_IN_EYE; // now it is // verify observer target again - if( m_hObserverTarget != NULL ) + if( m_hObserverTarget != 0 ) { CBaseEntity *pEnt = m_hObserverTarget; if( ( pEnt == this ) || ( pEnt == NULL ) ) - m_hObserverTarget = NULL; + m_hObserverTarget = 0; else if( ( (CBasePlayer*)pEnt )->IsObserver() || ( pEnt->pev->effects & EF_NODRAW ) ) - m_hObserverTarget = NULL; + m_hObserverTarget = 0; } // set spectator mode pev->iuser1 = iMode; // if we are not roaming, we need a valid target to track - if( ( iMode != OBS_ROAMING ) && ( m_hObserverTarget == NULL ) ) + if( ( iMode != OBS_ROAMING ) && ( m_hObserverTarget == 0 ) ) { Observer_FindNextPlayer( false ); // if we didn't find a valid target switch to roaming - if( m_hObserverTarget == NULL ) + if( m_hObserverTarget == 0 ) { ClientPrint( pev, HUD_PRINTCENTER, "#Spec_NoTarget" ); pev->iuser1 = OBS_ROAMING; diff --git a/dlls/osprey.cpp b/dlls/osprey.cpp index 95088d2b..6a421645 100644 --- a/dlls/osprey.cpp +++ b/dlls/osprey.cpp @@ -261,7 +261,7 @@ BOOL COsprey::HasDead() { for( int i = 0; i < m_iUnits; i++ ) { - if( m_hGrunt[i] == NULL || !m_hGrunt[i]->IsAlive() ) + if( m_hGrunt[i] == 0 || !m_hGrunt[i]->IsAlive() ) { return TRUE; } @@ -285,9 +285,9 @@ CBaseMonster *COsprey::MakeGrunt( Vector vecSrc ) for( int i = 0; i < m_iUnits; i++ ) { - if( m_hGrunt[i] == NULL || !m_hGrunt[i]->IsAlive() ) + if( m_hGrunt[i] == 0 || !m_hGrunt[i]->IsAlive() ) { - if( m_hGrunt[i] != NULL && m_hGrunt[i]->pev->rendermode == kRenderNormal ) + if( m_hGrunt[i] != 0 && m_hGrunt[i]->pev->rendermode == kRenderNormal ) { m_hGrunt[i]->SUB_StartFadeOut(); } @@ -319,7 +319,7 @@ void COsprey::HoverThink( void ) int i; for( i = 0; i < 4; i++ ) { - if( m_hRepel[i] != NULL && m_hRepel[i]->pev->health > 0 && !( m_hRepel[i]->pev->flags & FL_ONGROUND ) ) + if( m_hRepel[i] != 0 && m_hRepel[i]->pev->health > 0 && !( m_hRepel[i]->pev->flags & FL_ONGROUND ) ) { break; } diff --git a/dlls/plats.cpp b/dlls/plats.cpp index 93fb22fe..8fecf684 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -82,12 +82,12 @@ void CBasePlatTrain::KeyValue( KeyValueData *pkvd ) } else if( FStrEq( pkvd->szKeyName, "movesnd" ) ) { - m_bMoveSnd = atof( pkvd->szValue ); + m_bMoveSnd = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "stopsnd" ) ) { - m_bStopSnd = atof( pkvd->szValue ); + m_bStopSnd = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } else if( FStrEq( pkvd->szKeyName, "volume" ) ) @@ -1437,7 +1437,7 @@ void CFuncTrackTrain::Spawn( void ) pev->speed = 0; pev->velocity = g_vecZero; pev->avelocity = g_vecZero; - pev->impulse = m_speed; + pev->impulse = (int)m_speed; m_dir = 1; @@ -2212,7 +2212,7 @@ void CGunTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us { pev->takedamage = DAMAGE_AIM; m_hTargetEnt = GetNextTarget(); - if( m_hTargetEnt == NULL ) + if( m_hTargetEnt == 0 ) return; pev->health = pev->max_health; Next(); diff --git a/dlls/player.cpp b/dlls/player.cpp index 7d7363b5..51995acf 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -459,7 +459,7 @@ int CBasePlayer::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, fl } // keep track of amount of damage last sustained - m_lastDamageAmount = flDamage; + m_lastDamageAmount = (int)flDamage; // Armor. if( pev->armorvalue && !( bitsDamageType & ( DMG_FALL | DMG_DROWN ) ) )// armor doesn't protect against fall or drown damage! @@ -787,7 +787,7 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit ) m_pLastItem = NULL; - if( m_pTank != NULL ) + if( m_pTank != 0 ) { m_pTank->Use( this, this, USE_OFF, 0 ); m_pTank = NULL; @@ -847,7 +847,7 @@ void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib ) g_pGameRules->PlayerKilled( this, pevAttacker, g_pevLastInflictor ); - if( m_pTank != NULL ) + if( m_pTank != 0 ) { m_pTank->Use( this, this, USE_OFF, 0 ); m_pTank = NULL; @@ -1172,7 +1172,7 @@ void CBasePlayer::WaterMove() // track drowning damage, give it back when // player finally takes a breath - m_idrowndmg += pev->dmg; + m_idrowndmg += (int)pev->dmg; } } else @@ -1393,7 +1393,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) if( m_pActiveItem ) m_pActiveItem->Holster(); - if( m_pTank != NULL ) + if( m_pTank != 0 ) { m_pTank->Use( this, this, USE_OFF, 0 ); m_pTank = NULL; @@ -1468,7 +1468,7 @@ void CBasePlayer::PlayerUse( void ) // Hit Use on a train? if( m_afButtonPressed & IN_USE ) { - if( m_pTank != NULL ) + if( m_pTank != 0 ) { // Stop controlling the tank // TODO: Send HUD Update @@ -1491,7 +1491,7 @@ void CBasePlayer::PlayerUse( void ) if( pTrain && !( pev->button & IN_JUMP ) && FBitSet( pev->flags, FL_ONGROUND ) && (pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE ) && pTrain->OnControls( pev ) ) { m_afPhysicsFlags |= PFLAG_ONTRAIN; - m_iTrain = TrainSpeed( pTrain->pev->speed, pTrain->pev->impulse ); + m_iTrain = TrainSpeed( (int)pTrain->pev->speed, pTrain->pev->impulse ); m_iTrain |= TRAIN_NEW; EMIT_SOUND( ENT( pev ), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM ); return; @@ -1662,7 +1662,7 @@ void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) if( -score > pev->frags ) // Will this go negative? { - score = -pev->frags; // Sum will be 0 + score = (int)( -pev->frags ); // Sum will be 0 } } } @@ -1671,7 +1671,7 @@ void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); WRITE_BYTE( ENTINDEX( edict() ) ); - WRITE_SHORT( pev->frags ); + WRITE_SHORT( (int)pev->frags ); WRITE_SHORT( m_iDeaths ); WRITE_SHORT( 0 ); WRITE_SHORT( g_pGameRules->GetTeamIndex( m_szTeamName ) + 1 ); @@ -1733,8 +1733,8 @@ void CBasePlayer::UpdateStatusBar() // allies and medics get to see the targets health if( g_pGameRules->PlayerRelationship( this, pEntity ) == GR_TEAMMATE ) { - newSBarState[SBAR_ID_TARGETHEALTH] = 100 * ( pEntity->pev->health / pEntity->pev->max_health ); - newSBarState[SBAR_ID_TARGETARMOR] = pEntity->pev->armorvalue; //No need to get it % based since 100 it's the max. + newSBarState[SBAR_ID_TARGETHEALTH] = (int)( 100 * ( pEntity->pev->health / pEntity->pev->max_health ) ); + newSBarState[SBAR_ID_TARGETARMOR] = (int)pEntity->pev->armorvalue; //No need to get it % based since 100 it's the max. } m_flStatusBarDisappearDelay = gpGlobals->time + 1.0; @@ -1899,7 +1899,7 @@ void CBasePlayer::PreThink( void ) if( vel ) { - m_iTrain = TrainSpeed( pTrain->pev->speed, pTrain->pev->impulse ); + m_iTrain = TrainSpeed( (int)pTrain->pev->speed, pTrain->pev->impulse ); m_iTrain |= TRAIN_ACTIVE|TRAIN_NEW; } } @@ -2010,7 +2010,7 @@ void CBasePlayer::CheckTimeBasedDamage() int i; BYTE bDuration = 0; - static float gtbdPrev = 0.0; + //static float gtbdPrev = 0.0; if( !( m_bitsDamageType & DMG_TIMEBASED ) ) return; @@ -2271,7 +2271,7 @@ void CBasePlayer::CheckSuitUpdate() // seconds, then we won't repeat playback of this word or sentence // for at least that number of seconds. -void CBasePlayer::SetSuitUpdate( char *name, int fgroup, int iNoRepeatTime ) +void CBasePlayer::SetSuitUpdate( const char *name, int fgroup, int iNoRepeatTime ) { int i; int isentence; @@ -2399,7 +2399,7 @@ void CBasePlayer::UpdatePlayerSound( void ) // is louder than his body/movement, use the weapon volume, else, use the body volume. if( FBitSet( pev->flags, FL_ONGROUND ) ) { - iBodyVolume = pev->velocity.Length(); + iBodyVolume = (int)pev->velocity.Length(); // clamp the noise that can be made by the body, in case a push trigger, // weapon recoil, or anything shoves the player abnormally fast. @@ -2432,7 +2432,7 @@ void CBasePlayer::UpdatePlayerSound( void ) } // decay weapon volume over time so bits_SOUND_COMBAT stays set for a while - m_iWeaponVolume -= 250 * gpGlobals->frametime; + m_iWeaponVolume -= (int)( 250 * gpGlobals->frametime ); if( m_iWeaponVolume < 0 ) { iVolume = 0; @@ -2450,7 +2450,7 @@ void CBasePlayer::UpdatePlayerSound( void ) } else if( iVolume > m_iTargetVolume ) { - iVolume -= 250 * gpGlobals->frametime; + iVolume -= (int)( 250 * gpGlobals->frametime ); if( iVolume < m_iTargetVolume ) { @@ -2479,7 +2479,7 @@ void CBasePlayer::UpdatePlayerSound( void ) } // keep track of virtual muzzle flash - m_iWeaponFlash -= 256 * gpGlobals->frametime; + m_iWeaponFlash -= (int)( 256 * gpGlobals->frametime ); if( m_iWeaponFlash < 0 ) m_iWeaponFlash = 0; @@ -2501,7 +2501,7 @@ void CBasePlayer::PostThink() goto pt_end; // Handle Tank controlling - if( m_pTank != NULL ) + if( m_pTank != 0 ) { // if they've moved too far from the gun, or selected a weapon, unuse the gun if( m_pTank->OnControls( pev ) && !pev->weaponmodel ) @@ -2565,7 +2565,7 @@ void CBasePlayer::PostThink() { if( m_flFallVelocity > 64 && !g_pGameRules->IsMultiplayer() ) { - CSoundEnt::InsertSound( bits_SOUND_PLAYER, pev->origin, m_flFallVelocity, 0.2 ); + CSoundEnt::InsertSound( bits_SOUND_PLAYER, pev->origin, (int)m_flFallVelocity, 0.2 ); // ALERT( at_console, "fall %f\n", m_flFallVelocity ); } m_flFallVelocity = 0; @@ -3195,7 +3195,7 @@ void CSprayCan::Think( void ) } else { - UTIL_PlayerDecalTrace( &tr, playernum, pev->frame, TRUE ); + UTIL_PlayerDecalTrace( &tr, playernum, (int)pev->frame, TRUE ); // Just painted last custom frame. if( pev->frame++ >= ( nFrames - 1 ) ) UTIL_Remove( this ); @@ -3682,7 +3682,7 @@ int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) // // Returns the unique ID for the ammo, or -1 if error // -int CBasePlayer::GiveAmmo( int iCount, char *szName, int iMax ) +int CBasePlayer::GiveAmmo( int iCount, const char *szName, int iMax ) { if( !szName ) { @@ -3756,10 +3756,10 @@ Called every frame by the player PostThink */ void CBasePlayer::ItemPostFrame() { - static int fInSelect = FALSE; + //static int fInSelect = FALSE; // check if the player is using a tank - if( m_pTank != NULL ) + if( m_pTank != 0 ) return; #if defined( CLIENT_WEAPONS ) @@ -3912,12 +3912,12 @@ void CBasePlayer::UpdateClientData( void ) WRITE_BYTE( iHealth ); MESSAGE_END(); - m_iClientHealth = pev->health; + m_iClientHealth = (int)pev->health; } if( pev->armorvalue != m_iClientBattery ) { - m_iClientBattery = pev->armorvalue; + m_iClientBattery = (int)pev->armorvalue; ASSERT( gmsgBattery > 0 ); @@ -3945,8 +3945,8 @@ void CBasePlayer::UpdateClientData( void ) int visibleDamageBits = m_bitsDamageType & DMG_SHOWNHUD; MESSAGE_BEGIN( MSG_ONE, gmsgDamage, NULL, pev ); - WRITE_BYTE( pev->dmg_save ); - WRITE_BYTE( pev->dmg_take ); + WRITE_BYTE( (int)pev->dmg_save ); + WRITE_BYTE( (int)pev->dmg_take ); WRITE_LONG( visibleDamageBits ); WRITE_COORD( damageOrigin.x ); WRITE_COORD( damageOrigin.y ); @@ -4211,8 +4211,8 @@ Vector CBasePlayer::GetAutoaimVector( float flDelta ) { SET_CROSSHAIRANGLE( edict(), -m_vecAutoAim.x, m_vecAutoAim.y ); - m_lastx = m_vecAutoAim.x; - m_lasty = m_vecAutoAim.y; + m_lastx = (int)m_vecAutoAim.x; + m_lasty = (int)m_vecAutoAim.y; } } @@ -4556,10 +4556,10 @@ public: void KeyValue( KeyValueData *pkvd ); int m_iPose;// which sequence to display -- temporary, don't need to save - static char *m_szPoses[4]; + static const char *m_szPoses[4]; }; -char *CDeadHEV::m_szPoses[] = +const char *CDeadHEV::m_szPoses[] = { "deadback", "deadsitting", @@ -4701,7 +4701,7 @@ void CRevertSaved::KeyValue( KeyValueData *pkvd ) void CRevertSaved::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), pev->renderamt, FFADE_OUT ); + UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), (int)pev->renderamt, FFADE_OUT ); pev->nextthink = gpGlobals->time + MessageTime(); SetThink( &CRevertSaved::MessageThink ); } diff --git a/dlls/player.h b/dlls/player.h index cb2bddf8..b2dce868 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -273,7 +273,7 @@ public: void GiveNamedItem( const char *szName ); void EnableControl(BOOL fControl); - int GiveAmmo( int iAmount, char *szName, int iMax ); + int GiveAmmo( int iAmount, const char *szName, int iMax ); void SendAmmoUpdate(void); void WaterMove( void ); @@ -281,7 +281,7 @@ public: void PlayerUse( void ); void CheckSuitUpdate(); - void SetSuitUpdate(char *name, int fgroup, int iNoRepeat); + void SetSuitUpdate( const char *name, int fgroup, int iNoRepeat ); void UpdateGeigerCounter( void ); void CheckTimeBasedDamage( void ); diff --git a/dlls/satchel.cpp b/dlls/satchel.cpp index 05d1fc8c..458ac532 100644 --- a/dlls/satchel.cpp +++ b/dlls/satchel.cpp @@ -92,7 +92,7 @@ void CSatchelCharge::Spawn( void ) void CSatchelCharge::SatchelSlide( CBaseEntity *pOther ) { - entvars_t *pevOther = pOther->pev; + //entvars_t *pevOther = pOther->pev; // don't hit the guy that launched this grenade if( pOther->edict() == pev->owner ) @@ -377,11 +377,11 @@ void CSatchel::Throw( void ) { if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ) { +#ifndef CLIENT_DLL Vector vecSrc = m_pPlayer->pev->origin; Vector vecThrow = gpGlobals->v_forward * 274 + m_pPlayer->pev->velocity; -#ifndef CLIENT_DLL CBaseEntity *pSatchel = Create( "monster_satchel", vecSrc, Vector( 0, 0, 0 ), m_pPlayer->edict() ); pSatchel->pev->velocity = vecThrow; pSatchel->pev->avelocity.y = 400; diff --git a/dlls/saverestore.h b/dlls/saverestore.h index a9ad2c54..4295871d 100644 --- a/dlls/saverestore.h +++ b/dlls/saverestore.h @@ -23,7 +23,7 @@ class CSaveRestoreBuffer public: CSaveRestoreBuffer( void ); CSaveRestoreBuffer( SAVERESTOREDATA *pdata ); - ~CSaveRestoreBuffer( void ); + virtual ~CSaveRestoreBuffer( void ); int EntityIndex( entvars_t *pevLookup ); int EntityIndex( edict_t *pentLookup ); @@ -41,6 +41,10 @@ protected: SAVERESTOREDATA *m_pdata; void BufferRewind( int size ); unsigned int HashString( const char *pszToken ); +private: + // effc++ rule 11 + void operator = ( CSaveRestoreBuffer& ); + CSaveRestoreBuffer( const CSaveRestoreBuffer& ); }; class CSave : public CSaveRestoreBuffer @@ -81,7 +85,7 @@ typedef struct class CRestore : public CSaveRestoreBuffer { public: - CRestore( SAVERESTOREDATA *pdata ) : CSaveRestoreBuffer( pdata ) { m_global = 0; m_precache = TRUE; } + CRestore( SAVERESTOREDATA *pdata ) : CSaveRestoreBuffer( pdata ), m_global(0), m_precache( TRUE ) { } int ReadEntVars( const char *pname, entvars_t *pev ); // entvars_t int ReadFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); int ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount, int startField, int size, char *pName, void *pData ); @@ -160,6 +164,9 @@ private: globalentity_t *Find( string_t globalname ); globalentity_t *m_pList; int m_listCount; + // effc++ rule 11 + void operator = ( CGlobalState& ); + CGlobalState( const CGlobalState& ); }; extern CGlobalState gGlobalState; diff --git a/dlls/schedule.cpp b/dlls/schedule.cpp index c28a88fa..4a5cefca 100644 --- a/dlls/schedule.cpp +++ b/dlls/schedule.cpp @@ -238,7 +238,7 @@ void CBaseMonster::MaintainSchedule( void ) { if( (m_afConditions && !HasConditions( bits_COND_SCHEDULE_DONE ) ) || ( m_pSchedule && (m_pSchedule->iInterruptMask & bits_COND_SCHEDULE_DONE ) ) || - ( ( m_MonsterState == MONSTERSTATE_COMBAT ) && ( m_hEnemy == NULL ) ) ) + ( ( m_MonsterState == MONSTERSTATE_COMBAT ) && ( m_hEnemy == 0 ) ) ) { GetIdealState(); } @@ -407,7 +407,7 @@ void CBaseMonster::RunTask( Task_t *pTask ) { float distance; - if( m_hTargetEnt == NULL ) + if( m_hTargetEnt == 0 ) TaskFail(); else { @@ -675,7 +675,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) } case TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY: { - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { TaskFail(); return; @@ -695,7 +695,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) } case TASK_FIND_FAR_NODE_COVER_FROM_ENEMY: { - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { TaskFail(); return; @@ -715,7 +715,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) } case TASK_FIND_NODE_COVER_FROM_ENEMY: { - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { TaskFail(); return; @@ -737,7 +737,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) { entvars_t *pevCover; - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { // Find cover from self if no enemy available pevCover = pev; @@ -821,7 +821,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) SetTurnActivity(); break; case TASK_FACE_TARGET: - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) { MakeIdealYaw( m_hTargetEnt->pev->origin ); SetTurnActivity(); @@ -904,7 +904,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) TaskComplete(); else { - if( m_hTargetEnt == NULL || !MoveToTarget( newActivity, 2 ) ) + if( m_hTargetEnt == 0 || !MoveToTarget( newActivity, 2 ) ) { TaskFail(); ALERT( at_aiconsole, "%s Failed to reach target!!!\n", STRING( pev->classname ) ); @@ -1043,7 +1043,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) case TASK_GET_PATH_TO_TARGET: { RouteClear(); - if( m_hTargetEnt != NULL && MoveToTarget( m_movementActivity, 1 ) ) + if( m_hTargetEnt != 0 && MoveToTarget( m_movementActivity, 1 ) ) { TaskComplete(); } @@ -1272,7 +1272,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) } case TASK_PLANT_ON_SCRIPT: { - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) { pev->origin = m_hTargetEnt->pev->origin; // Plant on target } @@ -1282,7 +1282,7 @@ void CBaseMonster::StartTask( Task_t *pTask ) } case TASK_FACE_SCRIPT: { - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) { pev->ideal_yaw = UTIL_AngleMod( m_hTargetEnt->pev->angles.y ); } diff --git a/dlls/scientist.cpp b/dlls/scientist.cpp index 4e60c58e..d7659c61 100644 --- a/dlls/scientist.cpp +++ b/dlls/scientist.cpp @@ -434,7 +434,7 @@ void CScientist::Scream( void ) Activity CScientist::GetStoppedActivity( void ) { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) return ACT_EXCITED; return CTalkMonster::GetStoppedActivity(); } @@ -510,7 +510,7 @@ void CScientist::RunTask( Task_t *pTask ) if( RANDOM_LONG( 0, 63 ) < 8 ) Scream(); - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { TaskFail(); } @@ -893,8 +893,8 @@ Schedule_t *CScientist::GetSchedule( void ) m_fearTime = gpGlobals->time; else if( DisregardEnemy( pEnemy ) ) // After 15 seconds of being hidden, return to alert { - m_hEnemy = NULL; - pEnemy = NULL; + m_hEnemy = 0; + pEnemy = 0; } } @@ -1021,12 +1021,12 @@ MONSTERSTATE CScientist::GetIdealState( void ) { // Strip enemy when going to alert m_IdealMonsterState = MONSTERSTATE_ALERT; - m_hEnemy = NULL; + m_hEnemy = 0; return m_IdealMonsterState; } // Follow if only scared a little - if( m_hTargetEnt != NULL ) + if( m_hTargetEnt != 0 ) { m_IdealMonsterState = MONSTERSTATE_ALERT; return m_IdealMonsterState; @@ -1050,7 +1050,7 @@ MONSTERSTATE CScientist::GetIdealState( void ) BOOL CScientist::CanHeal( void ) { - if( ( m_healTime > gpGlobals->time ) || ( m_hTargetEnt == NULL ) || ( m_hTargetEnt->pev->health > ( m_hTargetEnt->pev->max_health * 0.5 ) ) ) + if( ( m_healTime > gpGlobals->time ) || ( m_hTargetEnt == 0 ) || ( m_hTargetEnt->pev->health > ( m_hTargetEnt->pev->max_health * 0.5 ) ) ) return FALSE; return TRUE; @@ -1093,10 +1093,10 @@ public: void KeyValue( KeyValueData *pkvd ); int m_iPose;// which sequence to display - static char *m_szPoses[7]; + static const char *m_szPoses[7]; }; -char *CDeadScientist::m_szPoses[] = +const char *CDeadScientist::m_szPoses[] = { "lying_on_back", "lying_on_stomach", diff --git a/dlls/scripted.cpp b/dlls/scripted.cpp index f3cf37c5..da9708d1 100644 --- a/dlls/scripted.cpp +++ b/dlls/scripted.cpp @@ -1068,7 +1068,7 @@ BOOL CScriptedSentence::AcceptableSpeaker( CBaseMonster *pMonster ) { if( pev->spawnflags & SF_SENTENCE_FOLLOWERS ) { - if( pMonster->m_hTargetEnt == NULL || !FClassnameIs( pMonster->m_hTargetEnt->pev, "player" ) ) + if( pMonster->m_hTargetEnt == 0 || !FClassnameIs( pMonster->m_hTargetEnt->pev, "player" ) ) return FALSE; } BOOL override; @@ -1124,7 +1124,7 @@ BOOL CScriptedSentence::StartSentence( CBaseMonster *pTarget ) if( !pTarget ) { ALERT( at_aiconsole, "Not Playing sentence %s\n", STRING( m_iszSentence ) ); - return NULL; + return FALSE; } BOOL bConcurrent = FALSE; diff --git a/dlls/skill.cpp b/dlls/skill.cpp index 2a68e1a5..689bbadb 100644 --- a/dlls/skill.cpp +++ b/dlls/skill.cpp @@ -25,13 +25,12 @@ skilldata_t gSkillData; // take the name of a cvar, tack a digit for the skill level // on, and return the value.of that Cvar //========================================================= -float GetSkillCvar( char *pName ) +float GetSkillCvar( const char *pName ) { - int iCount; float flValue; char szBuffer[64]; - iCount = sprintf( szBuffer, "%s%d",pName, gSkillData.iSkillLevel ); + sprintf( szBuffer, "%s%d",pName, gSkillData.iSkillLevel ); flValue = CVAR_GET_FLOAT( szBuffer ); diff --git a/dlls/skill.h b/dlls/skill.h index 5e784bed..12b784e3 100644 --- a/dlls/skill.h +++ b/dlls/skill.h @@ -136,7 +136,7 @@ struct skilldata_t }; extern DLL_GLOBAL skilldata_t gSkillData; -float GetSkillCvar( char *pName ); +float GetSkillCvar( const char *pName ); extern DLL_GLOBAL int g_iSkillLevel; diff --git a/dlls/sound.cpp b/dlls/sound.cpp index b97eee12..f6110a8d 100644 --- a/dlls/sound.cpp +++ b/dlls/sound.cpp @@ -448,7 +448,7 @@ void CAmbientGeneric::InitModulationParms( void ) { int pitchinc; - m_dpv.volrun = pev->health * 10; // 0 - 100 + m_dpv.volrun = (int)( pev->health * 10 ); // 0 - 100 if( m_dpv.volrun > 100 ) m_dpv.volrun = 100; if( m_dpv.volrun < 0 ) @@ -553,7 +553,7 @@ void CAmbientGeneric::ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, if( fraction < 0.0 ) fraction = 0.01; - m_dpv.pitch = fraction * 255; + m_dpv.pitch = (int)( fraction * 255 ); UTIL_EmitAmbientSound( ENT( pev ), pev->origin, szSoundFile, 0, 0, SND_CHANGE_PITCH, m_dpv.pitch ); return; @@ -1610,7 +1610,7 @@ float TEXTURETYPE_PlaySound( TraceResult *ptr, Vector vecSrc, Vector vecEnd, in const char *pTextureName; float rgfl1[3]; float rgfl2[3]; - char *rgsz[4]; + const char *rgsz[4]; int cnt; float fattn = ATTN_NORM; @@ -1822,7 +1822,7 @@ IMPLEMENT_SAVERESTORE( CSpeaker, CBaseEntity ) // void CSpeaker::Spawn( void ) { - char *szSoundFile = (char*) STRING( pev->message ); + const char *szSoundFile = STRING( pev->message ); if( !m_preset && ( FStringNull( pev->message ) || strlen( szSoundFile ) < 1 ) ) { @@ -1854,7 +1854,7 @@ void CSpeaker::Precache( void ) } void CSpeaker::SpeakerThink( void ) { - char* szSoundFile; + const char* szSoundFile = NULL; float flvolume = pev->health * 0.1; float flattenuation = 0.3; int flags = 0; @@ -1911,7 +1911,7 @@ void CSpeaker::SpeakerThink( void ) } } else - szSoundFile = (char*)STRING( pev->message ); + szSoundFile = STRING( pev->message ); if( szSoundFile[0] == '!' ) { diff --git a/dlls/squadmonster.cpp b/dlls/squadmonster.cpp index a89f39f9..3d476b50 100644 --- a/dlls/squadmonster.cpp +++ b/dlls/squadmonster.cpp @@ -192,7 +192,7 @@ BOOL CSquadMonster::SquadAdd( CSquadMonster *pAdd ) for( int i = 0; i < MAX_SQUAD_MEMBERS - 1; i++ ) { - if( m_hSquadMember[i] == NULL ) + if( m_hSquadMember[i] == 0 ) { m_hSquadMember[i] = pAdd; pAdd->m_hSquadLeader = this; @@ -258,7 +258,7 @@ void CSquadMonster::SquadMakeEnemy( CBaseEntity *pEnemy ) // reset members who aren't activly engaged in fighting if( pMember->m_hEnemy != pEnemy && !pMember->HasConditions( bits_COND_SEE_ENEMY ) ) { - if( pMember->m_hEnemy != NULL ) + if( pMember->m_hEnemy != 0 ) { // remember their current enemy pMember->PushEnemy( pMember->m_hEnemy, pMember->m_vecEnemyLKP ); @@ -459,7 +459,7 @@ BOOL CSquadMonster::NoFriendlyFire( void ) Vector v_left; //!!!BUGBUG - to fix this, the planes must be aligned to where the monster will be firing its gun, not the direction it is facing!!! - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { UTIL_MakeVectors( UTIL_VecToAngles( m_hEnemy->Center() - pev->origin ) ); } @@ -508,9 +508,7 @@ BOOL CSquadMonster::NoFriendlyFire( void ) //========================================================= MONSTERSTATE CSquadMonster::GetIdealState ( void ) { - int iConditions; - - iConditions = IScheduleFlags(); + IScheduleFlags(); // If no schedule conditions, the new ideal state is probably the reason we're in here. switch( m_MonsterState ) @@ -565,7 +563,7 @@ BOOL CSquadMonster::SquadEnemySplit( void ) for( int i = 0; i < MAX_SQUAD_MEMBERS; i++ ) { CSquadMonster *pMember = pSquadLeader->MySquadMember( i ); - if( pMember != NULL && pMember->m_hEnemy != NULL && pMember->m_hEnemy != pEnemy ) + if( pMember != NULL && pMember->m_hEnemy != 0 && pMember->m_hEnemy != pEnemy ) { return TRUE; } diff --git a/dlls/squadmonster.h b/dlls/squadmonster.h index ecd75ee5..707910c2 100644 --- a/dlls/squadmonster.h +++ b/dlls/squadmonster.h @@ -88,7 +88,7 @@ public: else return (CSquadMonster *)( (CBaseEntity *)m_hSquadMember[i] ); } - int InSquad( void ) { return m_hSquadLeader != NULL; } + int InSquad( void ) { return m_hSquadLeader != 0; } int IsLeader( void ) { return m_hSquadLeader == this; } int SquadJoin( int searchRadius ); int SquadRecruit( int searchRadius, int maxMembers ); diff --git a/dlls/squeakgrenade.cpp b/dlls/squeakgrenade.cpp index 30ddda62..830cfab8 100644 --- a/dlls/squeakgrenade.cpp +++ b/dlls/squeakgrenade.cpp @@ -94,7 +94,7 @@ int CSqueakGrenade::Classify( void ) if( m_iMyClass != 0 ) return m_iMyClass; // protect against recursion - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { m_iMyClass = CLASS_INSECT; // no one cares about it switch( m_hEnemy->Classify() ) @@ -180,13 +180,13 @@ void CSqueakGrenade::Killed( entvars_t *pevAttacker, int iGib ) UTIL_BloodDrips( pev->origin, g_vecZero, BloodColor(), 80 ); - if( m_hOwner != NULL ) + if( m_hOwner != 0 ) RadiusDamage( pev, m_hOwner->pev, pev->dmg, CLASS_NONE, DMG_BLAST ); else RadiusDamage( pev, pev, pev->dmg, CLASS_NONE, DMG_BLAST ); // reset owner so death message happens - if( m_hOwner != NULL ) + if( m_hOwner != 0 ) pev->owner = m_hOwner->edict(); CBaseMonster::Killed( pevAttacker, GIB_ALWAYS ); @@ -230,7 +230,7 @@ void CSqueakGrenade::HuntThink( void ) pev->velocity = pev->velocity * 0.9; pev->velocity.z += 8.0; } - else if( ( pev->movetype = MOVETYPE_FLY ) ) + else if( pev->movetype == MOVETYPE_FLY ) { pev->movetype = MOVETYPE_BOUNCE; } @@ -241,7 +241,7 @@ void CSqueakGrenade::HuntThink( void ) m_flNextHunt = gpGlobals->time + 2.0; - CBaseEntity *pOther = NULL; + //CBaseEntity *pOther = NULL; Vector vecDir; TraceResult tr; @@ -251,7 +251,7 @@ void CSqueakGrenade::HuntThink( void ) UTIL_MakeVectors( pev->angles ); - if( m_hEnemy == NULL || !m_hEnemy->IsAlive() ) + if( m_hEnemy == 0 || !m_hEnemy->IsAlive() ) { // find target, bounce a bit towards it. Look( 512 ); @@ -270,7 +270,7 @@ void CSqueakGrenade::HuntThink( void ) if( flpitch < 80 ) flpitch = 80; - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { if( FVisible( m_hEnemy ) ) { @@ -350,9 +350,9 @@ void CSqueakGrenade::SuperBounceTouch( CBaseEntity *pOther ) if( tr.pHit->v.modelindex != pev->modelindex ) { // ALERT( at_console, "hit enemy\n" ); - ClearMultiDamage( ); + ClearMultiDamage(); pOther->TraceAttack( pev, gSkillData.snarkDmgBite, gpGlobals->v_forward, &tr, DMG_SLASH ); - if( m_hOwner != NULL ) + if( m_hOwner != 0 ) ApplyMultiDamage( pev, m_hOwner->pev ); else ApplyMultiDamage( pev, pev ); diff --git a/dlls/talkmonster.cpp b/dlls/talkmonster.cpp index d832c2cc..35bf3856 100644 --- a/dlls/talkmonster.cpp +++ b/dlls/talkmonster.cpp @@ -51,7 +51,7 @@ TYPEDESCRIPTION CTalkMonster::m_SaveData[] = IMPLEMENT_SAVERESTORE( CTalkMonster, CBaseMonster ) // array of friend names -char *CTalkMonster::m_szFriends[TLK_CFRIENDS] = +const char *CTalkMonster::m_szFriends[TLK_CFRIENDS] = { "monster_barney", "monster_scientist", @@ -391,7 +391,7 @@ void CTalkMonster::StartTask( Task_t *pTask ) case TASK_TLK_EYECONTACT: break; case TASK_TLK_IDEALYAW: - if( m_hTalkTarget != NULL ) + if( m_hTalkTarget != 0 ) { pev->yaw_speed = 60; float yaw = VecToYaw( m_hTalkTarget->pev->origin - pev->origin ) - pev->angles.y; @@ -536,7 +536,7 @@ void CTalkMonster::RunTask( Task_t *pTask ) } break; case TASK_TLK_EYECONTACT: - if( !IsMoving() && IsTalking() && m_hTalkTarget != NULL ) + if( !IsMoving() && IsTalking() && m_hTalkTarget != 0 ) { // ALERT( at_console, "waiting %f\n", m_flStopTalkTime - gpGlobals->time ); IdleHeadTurn( m_hTalkTarget->pev->origin ); @@ -561,7 +561,7 @@ void CTalkMonster::RunTask( Task_t *pTask ) } break; case TASK_WAIT_FOR_MOVEMENT: - if( IsTalking() && m_hTalkTarget != NULL ) + if( IsTalking() && m_hTalkTarget != 0 ) { // ALERT( at_console, "walking, talking\n" ); IdleHeadTurn( m_hTalkTarget->pev->origin ); @@ -582,7 +582,7 @@ void CTalkMonster::RunTask( Task_t *pTask ) IdleHeadTurn( pev->origin ); break; default: - if( IsTalking() && m_hTalkTarget != NULL ) + if( IsTalking() && m_hTalkTarget != 0 ) { IdleHeadTurn( m_hTalkTarget->pev->origin ); } @@ -603,7 +603,7 @@ void CTalkMonster::Killed( entvars_t *pevAttacker, int iGib ) LimitFollowers( CBaseEntity::Instance( pevAttacker ), 0 ); } - m_hTargetEnt = NULL; + m_hTargetEnt = 0; // Don't finish that sentence StopTalking(); SetUse( NULL ); @@ -613,7 +613,7 @@ void CTalkMonster::Killed( entvars_t *pevAttacker, int iGib ) CBaseEntity *CTalkMonster::EnumFriends( CBaseEntity *pPrevious, int listNumber, BOOL bTrace ) { CBaseEntity *pFriend = pPrevious; - char *pszFriend; + const char *pszFriend; TraceResult tr; Vector vecCheck; @@ -712,7 +712,7 @@ void CTalkMonster::LimitFollowers( CBaseEntity *pPlayer, int maxFollowers ) float CTalkMonster::TargetDistance( void ) { // If we lose the player, or he dies, return a really large distance - if( m_hTargetEnt == NULL || !m_hTargetEnt->IsAlive() ) + if( m_hTargetEnt == 0 || !m_hTargetEnt->IsAlive() ) return 1e6; return ( m_hTargetEnt->pev->origin - pev->origin ).Length(); @@ -764,7 +764,7 @@ CBaseEntity *CTalkMonster::FindNearestFriend( BOOL fPlayer ) Vector vecStart = pev->origin; Vector vecCheck; int i; - char *pszFriend; + const char *pszFriend; int cfriends; vecStart.z = pev->absmax.z; @@ -855,7 +855,7 @@ void CTalkMonster::Touch( CBaseEntity *pOther ) //========================================================= void CTalkMonster::IdleRespond( void ) { - int pitch = GetVoicePitch(); + //int pitch = GetVoicePitch(); // play response PlaySentence( m_szGrp[TLK_ANSWER], RANDOM_FLOAT( 2.8, 3.2 ), VOL_NORM, ATTN_IDLE ); @@ -890,7 +890,7 @@ int CTalkMonster::FOkToSpeak( void ) return FALSE; // don't talk if you're in combat - if( m_hEnemy != NULL && FVisible( m_hEnemy ) ) + if( m_hEnemy != 0 && FVisible( m_hEnemy ) ) return FALSE; return TRUE; @@ -977,7 +977,7 @@ void CTalkMonster::IdleHeadTurn( Vector &vecFriend ) int CTalkMonster::FIdleSpeak( void ) { // try to start a conversation, or make statement - int pitch; + //int pitch; const char *szIdleGroup; const char *szQuestionGroup; float duration; @@ -1001,7 +1001,7 @@ int CTalkMonster::FIdleSpeak( void ) duration = RANDOM_FLOAT( 2.8, 3.2 ); } - pitch = GetVoicePitch(); + //pitch = GetVoicePitch(); // player using this entity is alive and wounded? CBaseEntity *pTarget = m_hTargetEnt; @@ -1315,10 +1315,10 @@ void CTalkMonster::StopFollowing( BOOL clearSchedule ) if( m_movementGoal == MOVEGOAL_TARGETENT ) RouteClear(); // Stop him from walking toward the player - m_hTargetEnt = NULL; + m_hTargetEnt = 0; if( clearSchedule ) ClearSchedule(); - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) m_IdealMonsterState = MONSTERSTATE_COMBAT; } } @@ -1328,7 +1328,7 @@ void CTalkMonster::StartFollowing( CBaseEntity *pLeader ) if( m_pCine ) m_pCine->CancelScript(); - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) m_IdealMonsterState = MONSTERSTATE_ALERT; m_hTargetEnt = pLeader; diff --git a/dlls/talkmonster.h b/dlls/talkmonster.h index 57c417e4..72222aae 100644 --- a/dlls/talkmonster.h +++ b/dlls/talkmonster.h @@ -138,7 +138,7 @@ public: // For following BOOL CanFollow( void ); - BOOL IsFollowing( void ) { return m_hTargetEnt != NULL && m_hTargetEnt->IsPlayer(); } + BOOL IsFollowing( void ) { return m_hTargetEnt != 0 && m_hTargetEnt->IsPlayer(); } void StopFollowing( BOOL clearSchedule ); void StartFollowing( CBaseEntity *pLeader ); virtual void DeclineFollowing( void ) {} @@ -154,7 +154,7 @@ public: static TYPEDESCRIPTION m_SaveData[]; - static char *m_szFriends[TLK_CFRIENDS]; // array of friend names + static const char *m_szFriends[TLK_CFRIENDS]; // array of friend names static float g_talkWaitTime; int m_bitsSaid; // set bits for sentences we don't want repeated diff --git a/dlls/teamplay_gamerules.cpp b/dlls/teamplay_gamerules.cpp index 614bd7bb..87b695e7 100644 --- a/dlls/teamplay_gamerules.cpp +++ b/dlls/teamplay_gamerules.cpp @@ -116,7 +116,7 @@ void CHalfLifeTeamplay::Think( void ) return; } - remain = flFragLimit - team_scores[i]; + remain = (int)( flFragLimit - team_scores[i] ); if( remain < bestfrags ) { bestfrags = remain; @@ -157,7 +157,7 @@ BOOL CHalfLifeTeamplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) if( CMD_ARGC() < 2 ) return TRUE; - int slot = atoi( CMD_ARGV( 1 ) ); + //int slot = atoi( CMD_ARGV( 1 ) ); // select the item from the current menu return TRUE; @@ -241,7 +241,7 @@ void CHalfLifeTeamplay::InitHUD( CBasePlayer *pPlayer ) ChangePlayerTeam( pPlayer, pPlayer->m_szTeamName, FALSE, FALSE ); UTIL_SayText( text, pPlayer ); - int clientIndex = pPlayer->entindex(); + //int clientIndex = pPlayer->entindex(); RecountTeams(); // update this player with all the other players team info // loop through all active players and send their team info to the new client @@ -300,7 +300,7 @@ void CHalfLifeTeamplay::ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTea MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); WRITE_BYTE( clientIndex ); - WRITE_SHORT( pPlayer->pev->frags ); + WRITE_SHORT( (int)pPlayer->pev->frags ); WRITE_SHORT( pPlayer->m_iDeaths ); WRITE_SHORT( 0 ); WRITE_SHORT( g_pGameRules->GetTeamIndex( pPlayer->m_szTeamName ) + 1 ); @@ -607,7 +607,7 @@ void CHalfLifeTeamplay::RecountTeams( bool bResendInfo ) if( tm >= 0 ) { - team_scores[tm] += plr->pev->frags; + team_scores[tm] += (int)plr->pev->frags; } if( bResendInfo ) //Someone's info changed, let's send the team info again. diff --git a/dlls/tentacle.cpp b/dlls/tentacle.cpp index 637b8946..44b8b45b 100644 --- a/dlls/tentacle.cpp +++ b/dlls/tentacle.cpp @@ -486,12 +486,12 @@ void CTentacle::Cycle( void ) m_flSoundYaw += 360; if( m_flSoundYaw > 180 ) m_flSoundYaw -= 360; - +#if 0 // ALERT( at_console, "sound %d %.0f\n", m_iSoundLevel, m_flSoundYaw ); if( m_flSoundTime < gpGlobals->time ) { // play "I hear new something" sound - char *sound; + const char *sound; switch( RANDOM_LONG( 0, 1 ) ) { @@ -505,6 +505,7 @@ void CTentacle::Cycle( void ) // UTIL_EmitAmbientSound( ENT( pev ), pev->origin + Vector( 0, 0, MyHeight() ), sound, 1.0, ATTN_NORM, 0, 100 ); } +#endif m_flSoundTime = gpGlobals->time + RANDOM_FLOAT( 5.0, 10.0 ); } @@ -591,7 +592,7 @@ void CTentacle::Cycle( void ) if( m_flNextSong < gpGlobals->time ) { // play "I hear new something" sound - char *sound; + const char *sound; switch( RANDOM_LONG( 0, 1 ) ) { @@ -791,7 +792,7 @@ void CTentacle::DieThink( void ) void CTentacle::HandleAnimEvent( MonsterEvent_t *pEvent ) { - char *sound; + const char *sound; switch( pEvent->event ) { diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index 958f899f..2959d96d 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -1265,7 +1265,7 @@ void CTriggerVolume::Spawn( void ) pev->solid = SOLID_NOT; pev->movetype = MOVETYPE_NONE; SET_MODEL( ENT(pev), STRING( pev->model ) ); // set size and link into world - pev->model = NULL; + pev->model = 0; pev->modelindex = 0; } @@ -1438,7 +1438,7 @@ void CChangeLevel::UseChangeLevel( CBaseEntity *pActivator, CBaseEntity *pCaller void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) { edict_t *pentLandmark; - LEVELLIST levels[16]; + //LEVELLIST levels[16]; ASSERT( !FStrEq( m_szMapName, "" ) ); @@ -2224,7 +2224,7 @@ void CTriggerCamera::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP } // Nothing to look at! - if( m_hTarget == NULL ) + if( m_hTarget == 0 ) { return; } @@ -2280,10 +2280,10 @@ void CTriggerCamera::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP void CTriggerCamera::FollowTarget() { - if( m_hPlayer == NULL ) + if( m_hPlayer == 0 ) return; - if( m_hTarget == NULL || m_flReturnTime < gpGlobals->time ) + if( m_hTarget == 0 || m_flReturnTime < gpGlobals->time ) { if( m_hPlayer->IsAlive() ) { diff --git a/dlls/tripmine.cpp b/dlls/tripmine.cpp index e2ed0817..520206dd 100644 --- a/dlls/tripmine.cpp +++ b/dlls/tripmine.cpp @@ -162,7 +162,7 @@ void CTripmineGrenade::PowerupThink( void ) { TraceResult tr; - if( m_hOwner == NULL ) + if( m_hOwner == 0 ) { // find an owner edict_t *oldowner = pev->owner; @@ -217,7 +217,7 @@ void CTripmineGrenade::PowerupThink( void ) MakeBeam(); // play enabled sound - EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "weapons/mine_activate.wav", 0.5, ATTN_NORM, 1.0, 75 ); + EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, "weapons/mine_activate.wav", 0.5, ATTN_NORM, 1, 75 ); } pev->nextthink = gpGlobals->time + 0.1; } @@ -280,7 +280,7 @@ void CTripmineGrenade::BeamBreakThink( void ) } else { - if( m_hOwner == NULL ) + if( m_hOwner == 0 ) bBlowup = 1; else if( m_posOwner != m_hOwner->pev->origin ) bBlowup = 1; @@ -446,7 +446,7 @@ void CTripmine::PrimaryAttack( void ) { Vector angles = UTIL_VecToAngles( tr.vecPlaneNormal ); - CBaseEntity *pEnt = CBaseEntity::Create( "monster_tripmine", tr.vecEndPos + tr.vecPlaneNormal * 8, angles, m_pPlayer->edict() ); + CBaseEntity::Create( "monster_tripmine", tr.vecEndPos + tr.vecPlaneNormal * 8, angles, m_pPlayer->edict() ); m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; diff --git a/dlls/turret.cpp b/dlls/turret.cpp index 2dce87fb..5b9e1b77 100644 --- a/dlls/turret.cpp +++ b/dlls/turret.cpp @@ -456,7 +456,7 @@ void CBaseTurret::ActiveThink( void ) pev->nextthink = gpGlobals->time + 0.1; StudioFrameAdvance(); - if( ( !m_iOn ) || ( m_hEnemy == NULL ) ) + if( ( !m_iOn ) || ( m_hEnemy == 0 ) ) { m_hEnemy = NULL; m_flLastSight = gpGlobals->time + m_flMaxWait; @@ -826,21 +826,21 @@ void CBaseTurret::SearchThink( void ) Ping(); // If we have a target and we're still healthy - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { if( !m_hEnemy->IsAlive() ) m_hEnemy = NULL;// Dead enemy forces a search for new one } // Acquire Target - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { Look( TURRET_RANGE ); m_hEnemy = BestVisibleEnemy(); } // If we've found a target, spin up the barrel and start to attack - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { m_flLastSight = 0; m_flSpinUpTime = 0; @@ -881,20 +881,20 @@ void CBaseTurret::AutoSearchThink( void ) pev->nextthink = gpGlobals->time + 0.3; // If we have a target and we're still healthy - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { if( !m_hEnemy->IsAlive() ) m_hEnemy = NULL;// Dead enemy forces a search for new one } // Acquire Target - if( m_hEnemy == NULL ) + if( m_hEnemy == 0 ) { Look( TURRET_RANGE ); m_hEnemy = BestVisibleEnemy(); } - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { SetThink( &CBaseTurret::Deploy ); EMIT_SOUND( ENT( pev ), CHAN_BODY, "turret/tu_alert.wav", TURRET_MACHINE_VOLUME, ATTN_NORM ); @@ -903,7 +903,7 @@ void CBaseTurret::AutoSearchThink( void ) void CBaseTurret::TurretDeath( void ) { - BOOL iActive = FALSE; + //BOOL iActive = FALSE; StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; @@ -1222,7 +1222,7 @@ void CSentry::SentryTouch( CBaseEntity *pOther ) void CSentry::SentryDeath( void ) { - BOOL iActive = FALSE; + //BOOL iActive = FALSE; StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; diff --git a/dlls/util.cpp b/dlls/util.cpp index 9c7d9803..d79c9f5a 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -118,7 +118,7 @@ float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ) U_Random(); U_Random(); - range = high - low; + range = (int)( high - low ); if( !range ) { return low; @@ -625,7 +625,7 @@ static unsigned short FixedUnsigned16( float value, float scale ) { int output; - output = value * scale; + output = (int)( value * scale ); if( output < 0 ) output = 0; if( output > 0xFFFF ) @@ -638,7 +638,7 @@ static short FixedSigned16( float value, float scale ) { int output; - output = value * scale; + output = (int)( value * scale ); if( output > 32767 ) output = 32767; @@ -937,10 +937,10 @@ TraceResult UTIL_GetGlobalTrace( ) { TraceResult tr; - tr.fAllSolid = gpGlobals->trace_allsolid; - tr.fStartSolid = gpGlobals->trace_startsolid; - tr.fInOpen = gpGlobals->trace_inopen; - tr.fInWater = gpGlobals->trace_inwater; + tr.fAllSolid = (int)gpGlobals->trace_allsolid; + tr.fStartSolid = (int)gpGlobals->trace_startsolid; + tr.fInOpen = (int)gpGlobals->trace_inopen; + tr.fInWater = (int)gpGlobals->trace_inwater; tr.flFraction = gpGlobals->trace_fraction; tr.flPlaneDist = gpGlobals->trace_plane_dist; tr.pHit = gpGlobals->trace_ent; @@ -1033,7 +1033,7 @@ float UTIL_SplineFraction( float value, float scale ) return 3 * valueSquared - 2 * valueSquared * value; } -char *UTIL_VarArgs( char *format, ... ) +char *UTIL_VarArgs( const char *format, ... ) { va_list argptr; static char string[1024]; @@ -1536,7 +1536,7 @@ void UTIL_PrecacheOther( const char *szClassname ) // UTIL_LogPrintf - Prints a logged message to console. // Preceded by LOG: ( timestamp ) < message > //========================================================= -void UTIL_LogPrintf( char *fmt, ... ) +void UTIL_LogPrintf( const char *fmt, ... ) { va_list argptr; static char string[1024]; @@ -1902,7 +1902,7 @@ void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ) int i; TYPEDESCRIPTION *pField; - for( i = 0; i < ENTVARS_COUNT; i++ ) + for( i = 0; i < (int)ENTVARS_COUNT; i++ ) { pField = &gEntvarsDescription[i]; diff --git a/dlls/util.h b/dlls/util.h index f8ae0b6a..fc345ae4 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -87,8 +87,9 @@ typedef int EOFFSET; typedef int BOOL; // In case this ever changes +#ifndef M_PI #define M_PI 3.14159265358979323846 - +#endif // Keeps clutter down a bit, when declaring external entity/global method prototypes #define DECLARE_GLOBAL_METHOD(MethodName) extern void DLLEXPORT MethodName( void ) #define GLOBAL_METHOD(funcname) void DLLEXPORT funcname(void) @@ -304,7 +305,7 @@ extern float UTIL_Approach( float target, float value, float speed ); extern float UTIL_ApproachAngle( float target, float value, float speed ); extern float UTIL_AngleDistance( float next, float cur ); -extern char *UTIL_VarArgs( char *format, ... ); +extern char *UTIL_VarArgs( const char *format, ... ); extern void UTIL_Remove( CBaseEntity *pEntity ); extern BOOL UTIL_IsValidEntity( edict_t *pent ); extern BOOL UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 ); @@ -364,7 +365,7 @@ extern char *UTIL_dtos3( int d ); extern char *UTIL_dtos4( int d ); // Writes message to console with timestamp and FragLog header. -extern void UTIL_LogPrintf( char *fmt, ... ); +extern void UTIL_LogPrintf( const char *fmt, ... ); // Sorta like FInViewCone, but for nonmonsters. extern float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ); @@ -534,7 +535,7 @@ void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg); void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); #define PRECACHE_SOUND_ARRAY( a ) \ - { for (int i = 0; i < ARRAYSIZE( a ); i++ ) PRECACHE_SOUND((char *) a [i]); } + { for (int i = 0; i < (int)ARRAYSIZE( a ); i++ ) PRECACHE_SOUND((char *) a [i]); } #define EMIT_SOUND_ARRAY_DYN( chan, array ) \ EMIT_SOUND_DYN ( ENT(pev), chan , array [ RANDOM_LONG(0,ARRAYSIZE( array )-1) ], 1.0, ATTN_NORM, 0, RANDOM_LONG(95,105) ); diff --git a/dlls/vector.h b/dlls/vector.h index d3347983..265a9b00 100644 --- a/dlls/vector.h +++ b/dlls/vector.h @@ -22,8 +22,8 @@ class Vector2D { public: - inline Vector2D(void) { } - inline Vector2D(float X, float Y) { x = X; y = Y; } + inline Vector2D(void): x( 0.0f ), y( 0.0f ) { } + inline Vector2D(float X, float Y): x( 0.0f ), y( 0.0f ) { x = X; y = Y; } inline Vector2D operator+(const Vector2D& v) const { return Vector2D( x + v.x, y + v.y ); } inline Vector2D operator-(const Vector2D& v) const { return Vector2D( x - v.x, y - v.y ); } inline Vector2D operator*(float fl) const { return Vector2D( x * fl, y * fl ); } @@ -33,7 +33,7 @@ public: inline Vector2D Normalize ( void ) const { - Vector2D vec2; + //Vector2D vec2; float flLen = Length(); if( flLen == 0 ) @@ -60,12 +60,12 @@ class Vector // same data-layout as engine's vec3_t, { // which is a vec_t[3] public: // Construction/destruction - inline Vector( void ) { } - inline Vector( float X, float Y, float Z ) { x = X; y = Y; z = Z; } + inline Vector( void ): x( 0.0f ), y( 0.0f ), z( 0.0f ) { } + inline Vector( float X, float Y, float Z ): x( 0.0f ), y( 0.0f ), z( 0.0f ) { x = X; y = Y; z = Z; } //inline Vector( double X, double Y, double Z ) { x = (float)X; y = (float)Y; z = (float)Z; } //inline Vector( int X, int Y, int Z ) { x = (float)X; y = (float)Y; z = (float)Z; } - inline Vector( const Vector& v ) { x = v.x; y = v.y; z = v.z; } - inline Vector( float rgfl[3] ) { x = rgfl[0]; y = rgfl[1]; z = rgfl[2]; } + inline Vector( const Vector& v ): x( 0.0f ), y( 0.0f ), z( 0.0f ) { x = v.x; y = v.y; z = v.z; } + inline Vector( float rgfl[3] ): x( 0.0f ), y( 0.0f ), z( 0.0f ) { x = rgfl[0]; y = rgfl[1]; z = rgfl[2]; } // Operators inline Vector operator-( void ) const { return Vector( -x, -y, -z ); } diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index ee2a8547..0b6f7de6 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -935,7 +935,7 @@ BOOL CBasePlayerWeapon::CanDeploy( void ) return TRUE; } -BOOL CBasePlayerWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal /* = 0 */, int body ) +BOOL CBasePlayerWeapon::DefaultDeploy( const char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal /* = 0 */, int body ) { if( !CanDeploy() ) return FALSE; @@ -1400,7 +1400,7 @@ BOOL CWeaponBox::PackAmmo( int iszName, int iCount ) //========================================================= // CWeaponBox - GiveAmmo //========================================================= -int CWeaponBox::GiveAmmo( int iCount, char *szName, int iMax, int *pIndex/* = NULL*/ ) +int CWeaponBox::GiveAmmo( int iCount, const char *szName, int iMax, int *pIndex/* = NULL*/ ) { int i; diff --git a/dlls/weapons.h b/dlls/weapons.h index 3e6fc5ce..8d60bad8 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -310,7 +310,7 @@ public: virtual BOOL CanDeploy( void ); virtual BOOL IsUseable( void ); - BOOL DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal = 0, int body = 0 ); + BOOL DefaultDeploy( const char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal = 0, int body = 0 ); int DefaultReload( int iClipSize, int iAnim, float fDelay, int body = 0 ); virtual void ItemPostFrame( void ); // called each frame by the player PostThink @@ -430,7 +430,7 @@ class CWeaponBox : public CBaseEntity void Touch( CBaseEntity *pOther ); void KeyValue( KeyValueData *pkvd ); BOOL IsEmpty( void ); - int GiveAmmo( int iCount, char *szName, int iMax, int *pIndex = NULL ); + int GiveAmmo( int iCount, const char *szName, int iMax, int *pIndex = NULL ); void SetObjectCollisionBox( void ); public: @@ -453,7 +453,7 @@ public: #ifdef CLIENT_DLL bool bIsMultiplayer ( void ); -void LoadVModel ( char *szViewModel, CBasePlayer *m_pPlayer ); +void LoadVModel ( const char *szViewModel, CBasePlayer *m_pPlayer ); #endif class CGlock : public CBasePlayerWeapon @@ -828,7 +828,9 @@ public: unsigned short m_usEgonStop; private: +#ifndef CLIENT_DLL float m_shootTime; +#endif EGON_FIREMODE m_fireMode; float m_shakeTime; BOOL m_deployed; diff --git a/dlls/world.cpp b/dlls/world.cpp index a065b5be..f352bd52 100644 --- a/dlls/world.cpp +++ b/dlls/world.cpp @@ -292,7 +292,7 @@ globalentity_t *CGlobalState::Find( string_t globalname ) //#ifdef _DEBUG void CGlobalState::DumpGlobals( void ) { - static char *estates[] = { "Off", "On", "Dead" }; + static const char *estates[] = { "Off", "On", "Dead" }; globalentity_t *pTest; ALERT( at_console, "-- Globals --\n" ); @@ -582,7 +582,7 @@ void CWorld::Precache( void ) // 63 testing LIGHT_STYLE( 63, "a" ); - for( int i = 0; i < ARRAYSIZE( gDecals ); i++ ) + for( int i = 0; i < (int)ARRAYSIZE( gDecals ); i++ ) gDecals[i].index = DECAL_INDEX( gDecals[i].name ); // init the WorldGraph. diff --git a/dlls/xen.cpp b/dlls/xen.cpp index 8e9c771c..4e9e1685 100644 --- a/dlls/xen.cpp +++ b/dlls/xen.cpp @@ -98,7 +98,7 @@ void CXenPLight::Spawn( void ) pev->frame = RANDOM_FLOAT( 0, 255 ); m_pGlow = CSprite::SpriteCreate( XEN_PLANT_GLOW_SPRITE, pev->origin + Vector(0,0,(pev->mins.z+pev->maxs.z)*0.5), FALSE ); - m_pGlow->SetTransparency( kRenderGlow, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, pev->renderamt, pev->renderfx ); + m_pGlow->SetTransparency( kRenderGlow, (int)pev->rendercolor.x, (int)pev->rendercolor.y, (int)pev->rendercolor.z, (int)pev->renderamt, (int)pev->renderfx ); m_pGlow->SetAttachment( edict(), 1 ); } @@ -497,7 +497,7 @@ void CXenSporeLarge::Spawn( void ) UTIL_MakeVectorsPrivate( pev->angles, forward, right, NULL ); // Rotate the leg hulls into position - for( int i = 0; i < ARRAYSIZE( m_hullSizes ); i++ ) + for( int i = 0; i < (int)ARRAYSIZE( m_hullSizes ); i++ ) CXenHull::CreateHull( this, Vector( -12, -12, 0 ), Vector( 12, 12, 120 ), ( m_hullSizes[i].x * forward ) + ( m_hullSizes[i].y * right ) ); } @@ -536,7 +536,7 @@ void CXenSpore::Touch( CBaseEntity *pOther ) void CXenSpore::Think( void ) { - float flInterval = StudioFrameAdvance(); + StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; #if 0 DispatchAnimEvents( flInterval ); diff --git a/dlls/zombie.cpp b/dlls/zombie.cpp index b20293c1..2611f881 100644 --- a/dlls/zombie.cpp +++ b/dlls/zombie.cpp @@ -286,7 +286,7 @@ void CZombie::Spawn() //========================================================= void CZombie::Precache() { - int i; + size_t i; PRECACHE_MODEL( "models/zombie.mdl" ); diff --git a/engine/custom.h b/engine/custom.h index d48ee72d..8f644e00 100644 --- a/engine/custom.h +++ b/engine/custom.h @@ -16,6 +16,12 @@ #ifndef CUSTOM_H #define CUSTOM_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + #include "const.h" ///////////////// diff --git a/engine/edict.h b/engine/edict.h index b0469b86..e89b6926 100644 --- a/engine/edict.h +++ b/engine/edict.h @@ -16,6 +16,12 @@ #ifndef EDICT_H #define EDICT_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + #define MAX_ENT_LEAFS 48 #include "progdefs.h" @@ -39,4 +45,4 @@ struct edict_s // other fields from progs come immediately after }; -#endif//EDICT_H \ No newline at end of file +#endif//EDICT_H diff --git a/engine/eiface.h b/engine/eiface.h index 3419e5bd..30f8a82a 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -94,13 +94,13 @@ typedef unsigned int CRC32_t; // Engine hands this to DLLs for functionality callbacks typedef struct enginefuncs_s { - int (*pfnPrecacheModel)( char* s ); - int (*pfnPrecacheSound)( char* s ); + int (*pfnPrecacheModel)( const char *s ); + int (*pfnPrecacheSound)( const char *s ); void (*pfnSetModel)( edict_t *e, const char *m ); int (*pfnModelIndex)( const char *m ); int (*pfnModelFrames)( int modelIndex ); void (*pfnSetSize)( edict_t *e, const float *rgflMin, const float *rgflMax ); - void (*pfnChangeLevel)( char* s1, char* s2 ); + void (*pfnChangeLevel)( const char *s1, const char *s2 ); void (*pfnGetSpawnParms)( edict_t *ent ); void (*pfnSaveSpawnParms)( edict_t *ent ); float (*pfnVecToYaw)( const float *rgflVector ); @@ -132,12 +132,12 @@ typedef struct enginefuncs_s void (*pfnTraceModel)( const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr ); const char *(*pfnTraceTexture)( edict_t *pTextureEntity, const float *v1, const float *v2 ); void (*pfnTraceSphere)( const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr ); - void (*pfnGetAimVector)( edict_t* ent, float speed, float *rgflReturn ); - void (*pfnServerCommand)( char* str ); + void (*pfnGetAimVector)( edict_t *ent, float speed, float *rgflReturn ); + void (*pfnServerCommand)( const char *str ); void (*pfnServerExecute)( void ); - void (*pfnClientCommand)( edict_t* pEdict, char* szFmt, ... ); + void (*pfnClientCommand)( edict_t* pEdict, const char *szFmt, ... ); void (*pfnParticleEffect)( const float *org, const float *dir, float color, float count ); - void (*pfnLightStyle)( int style, char* val ); + void (*pfnLightStyle)( int style, const char *val ); int (*pfnDecalIndex)( const char *name ); int (*pfnPointContents)( const float *rgflVector ); void (*pfnMessageBegin)( int msg_dest, int msg_type, const float *pOrigin, edict_t *ed ); @@ -155,8 +155,8 @@ typedef struct enginefuncs_s const char* (*pfnCVarGetString)( const char *szVarName ); void (*pfnCVarSetFloat)( const char *szVarName, float flValue ); void (*pfnCVarSetString)( const char *szVarName, const char *szValue ); - void (*pfnAlertMessage)( ALERT_TYPE atype, char *szFmt, ... ); - void (*pfnEngineFprintf)( FILE *pfile, char *szFmt, ... ); + void (*pfnAlertMessage)( ALERT_TYPE atype, const char *szFmt, ... ); + void (*pfnEngineFprintf)( FILE *pfile, const char *szFmt, ... ); void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, int cb ); void* (*pfnPvEntPrivateData)( edict_t *pEdict ); void (*pfnFreeEntPrivateData)( edict_t *pEdict ); @@ -189,7 +189,7 @@ typedef struct enginefuncs_s void (*pfnSetView)( const edict_t *pClient, const edict_t *pViewent ); float (*pfnTime)( void ); void (*pfnCrosshairAngle)( const edict_t *pClient, float pitch, float yaw ); - byte* (*pfnLoadFileForMe)( char *filename, int *pLength ); + byte* (*pfnLoadFileForMe)( const char *filename, int *pLength ); void (*pfnFreeFile)( void *buffer ); void (*pfnEndSection)( const char *pszSectionName ); // trigger_endsection int (*pfnCompareFileTime)( char *filename1, char *filename2, int *iCompare ); @@ -201,12 +201,12 @@ typedef struct enginefuncs_s void (*pfnRunPlayerMove)( edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec ); int (*pfnNumberOfEntities)( void ); char* (*pfnGetInfoKeyBuffer)( edict_t *e ); // passing in NULL gets the serverinfo - char* (*pfnInfoKeyValue)( char *infobuffer, char *key ); - void (*pfnSetKeyValue)( char *infobuffer, char *key, char *value ); - void (*pfnSetClientKeyValue)( int clientIndex, char *infobuffer, char *key, char *value ); - int (*pfnIsMapValid)( char *filename ); + char* (*pfnInfoKeyValue)( char *infobuffer, const char *key ); + void (*pfnSetKeyValue)( char *infobuffer, const char *key, const char *value ); + void (*pfnSetClientKeyValue)( int clientIndex, char *infobuffer, const char *key, const char *value ); + int (*pfnIsMapValid)( const char *filename ); void (*pfnStaticDecal)( const float *origin, int decalIndex, int entityIndex, int modelIndex ); - int (*pfnPrecacheGeneric)( char *s ); + int (*pfnPrecacheGeneric)( const char *s ); int (*pfnGetPlayerUserId)( edict_t *e ); // returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients void (*pfnBuildSoundMsg)( edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed ); int (*pfnIsDedicatedServer)( void ); // is this a dedicated server? @@ -228,7 +228,7 @@ typedef struct enginefuncs_s void (*pfnDeltaSetField) ( struct delta_s *pFields, const char *fieldname ); void (*pfnDeltaUnsetField)( struct delta_s *pFields, const char *fieldname ); - void (*pfnDeltaAddEncoder)( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); + void (*pfnDeltaAddEncoder)( const char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); int (*pfnGetCurrentPlayer)( void ); int (*pfnCanSkipPlayer)( const edict_t *player ); int (*pfnDeltaFindField)( struct delta_s *pFields, const char *fieldname ); @@ -236,7 +236,7 @@ typedef struct enginefuncs_s void (*pfnDeltaUnsetFieldByIndex)( struct delta_s *pFields, int fieldNumber ); void (*pfnSetGroupMask)( int mask, int op ); int (*pfnCreateInstancedBaseline)( int classname, struct entity_state_s *baseline ); - void (*pfnCvar_DirectSet)( struct cvar_s *var, char *value ); + void (*pfnCvar_DirectSet)( struct cvar_s *var, const char *value ); // Forces the client and server to be running with the same version of the specified file // ( e.g., a player model ). @@ -245,7 +245,7 @@ typedef struct enginefuncs_s void (*pfnGetPlayerStats)( const edict_t *pClient, int *ping, int *packet_loss ); - void (*pfnAddServerCommand)( char *cmd_name, void (*function) (void) ); + void (*pfnAddServerCommand)( const char *cmd_name, void (*function) (void) ); // For voice communications, set which clients hear eachother. // NOTE: these functions take player entity indices (starting at 1). @@ -256,7 +256,7 @@ typedef struct enginefuncs_s void *(*pfnSequenceGet)( const char *fileName, const char *entryName ); void *(*pfnSequencePickSentence)( const char *groupName, int pickMethod, int *picked ); - int (*pfnGetFileSize)( char *filename ); + int (*pfnGetFileSize)( const char *filename ); unsigned int (*pfnGetApproxWavePlayLen)( const char *filepath ); int (*pfnIsCareerMatch)( void ); int (*pfnGetLocalizedStringLength)( const char *label ); @@ -274,9 +274,9 @@ typedef struct enginefuncs_s // Passed to pfnKeyValue typedef struct KeyValueData_s { - char *szClassName; // in: entity classname - char *szKeyName; // in: name of key - char *szValue; // in: value of key + const char *szClassName; // in: entity classname + const char *szKeyName; // in: name of key + const char *szValue; // in: value of key int fHandled; // out: DLL sets to true if key-value pair was understood } KeyValueData; @@ -374,13 +374,15 @@ typedef enum _fieldtypes typedef struct { FIELDTYPE fieldType; - char *fieldName; + const char *fieldName; int fieldOffset; short fieldSize; short flags; } TYPEDESCRIPTION; +#ifndef ARRAYSIZE #define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) +#endif typedef struct { @@ -434,7 +436,7 @@ typedef struct void (*pfnPM_Move)( struct playermove_s *ppmove, qboolean server ); void (*pfnPM_Init)( struct playermove_s *ppmove ); - char (*pfnPM_FindTextureType)( char *name ); + char (*pfnPM_FindTextureType)( const char *name ); void (*pfnSetupVisibility)( struct edict_s *pViewEntity, struct edict_s *pClient, unsigned char **pvs, unsigned char **pas ); void (*pfnUpdateClientData) ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); int (*pfnAddToFullPack)( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ); diff --git a/engine/progdefs.h b/engine/progdefs.h index 74004a27..cdbcc006 100644 --- a/engine/progdefs.h +++ b/engine/progdefs.h @@ -16,6 +16,12 @@ #ifndef PROGDEFS_H #define PROGDEFS_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + typedef struct { float time; @@ -215,4 +221,4 @@ typedef struct entvars_s edict_t *euser4; } entvars_t; -#endif//PROGDEFS_H \ No newline at end of file +#endif//PROGDEFS_H diff --git a/pm_shared/pm_debug.c b/pm_shared/pm_debug.c index 3baccaef..3b0879c7 100644 --- a/pm_shared/pm_debug.c +++ b/pm_shared/pm_debug.c @@ -23,8 +23,10 @@ #include +#ifdef _MSC_VER #pragma warning(disable : 4244) #pragma warning(disable : 4305) +#endif extern playermove_t *pmove; diff --git a/pm_shared/pm_debug.h b/pm_shared/pm_debug.h index 4959d165..cc130598 100644 --- a/pm_shared/pm_debug.h +++ b/pm_shared/pm_debug.h @@ -15,6 +15,12 @@ #ifndef PM_DEBUG_H #define PM_DEBUG_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + void PM_ViewEntity( void ); void PM_DrawBBox( vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life ); void PM_ParticleLine( vec3_t start, vec3_t end, int pcolor, float life, float vert ); diff --git a/pm_shared/pm_defs.h b/pm_shared/pm_defs.h index cd17ce54..b4c652ba 100644 --- a/pm_shared/pm_defs.h +++ b/pm_shared/pm_defs.h @@ -16,6 +16,12 @@ #ifndef PM_DEFS_H #define PM_DEFS_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + #define MAX_PHYSENTS 600 // Must have room for all entities in the world. #define MAX_MOVEENTS 64 #define MAX_CLIP_PLANES 5 diff --git a/pm_shared/pm_info.h b/pm_shared/pm_info.h index 321527f2..d9dbc03d 100644 --- a/pm_shared/pm_info.h +++ b/pm_shared/pm_info.h @@ -15,5 +15,11 @@ #ifndef PM_INFO_H #define PM_INFO_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + #define MAX_PHYSINFO_STRING 256 #endif//PM_INFO_H diff --git a/pm_shared/pm_math.c b/pm_shared/pm_math.c index 3718dc63..5bbe0068 100644 --- a/pm_shared/pm_math.c +++ b/pm_shared/pm_math.c @@ -25,7 +25,9 @@ // fall over #define ROLL 2 +#ifdef _MSC_VER #pragma warning(disable : 4244) +#endif vec3_t vec3_origin = { 0,0,0 }; int nanmask = 255 << 23; diff --git a/pm_shared/pm_shared.c b/pm_shared/pm_shared.c index 7a1fb966..c709ba14 100644 --- a/pm_shared/pm_shared.c +++ b/pm_shared/pm_shared.c @@ -36,7 +36,9 @@ extern float vJumpAngles[3]; static int pm_shared_initialized = 0; +#ifdef _MSC_VER #pragma warning( disable : 4305 ) +#endif playermove_t *pmove = NULL; @@ -90,7 +92,10 @@ playermove_t *pmove = NULL; #define PLAYER_DUCKING_MULTIPLIER 0.333 // double to float warning +#ifdef _MSC_VER #pragma warning(disable : 4244) +#endif + #define max(a, b) (((a) > (b)) ? (a) : (b)) #define min(a, b) (((a) < (b)) ? (a) : (b)) // up / down @@ -549,7 +554,7 @@ void PM_UpdateStepSound( void ) float fvol; vec3_t knee; vec3_t feet; - vec3_t center; + //vec3_t center; float height; float speed; float velrun; @@ -592,7 +597,7 @@ void PM_UpdateStepSound( void ) { fWalking = speed < velrun; - VectorCopy( pmove->origin, center ); + //VectorCopy( pmove->origin, center ); VectorCopy( pmove->origin, knee ); VectorCopy( pmove->origin, feet ); @@ -1062,7 +1067,7 @@ Only used by players. Moves along the ground when player is a MOVETYPE_WALK. */ void PM_WalkMove() { - int clip; + //int clip; int oldonground; int i; @@ -1072,7 +1077,7 @@ void PM_WalkMove() vec3_t wishdir; float wishspeed; - vec3_t dest, start; + vec3_t dest; //, start; vec3_t original, originalvel; vec3_t down, downvel; float downdist, updist; @@ -1135,7 +1140,7 @@ void PM_WalkMove() dest[2] = pmove->origin[2]; // first try moving directly to the next spot - VectorCopy( dest, start ); + //VectorCopy( dest, start ); trace = pmove->PM_PlayerTrace( pmove->origin, dest, PM_NORMAL, -1 ); // If we made it all the way, then copy trace end // as new player position. @@ -1158,7 +1163,8 @@ void PM_WalkMove() VectorCopy( pmove->velocity, originalvel ); // velocity. // Slide move - clip = PM_FlyMove(); + //clip = PM_FlyMove(); + PM_FlyMove(); // Copy the results out VectorCopy( pmove->origin, down ); @@ -1183,7 +1189,8 @@ void PM_WalkMove() } // slide move the rest of the way. - clip = PM_FlyMove(); + //clip = PM_FlyMove(); + PM_FlyMove(); // Now try going back down from the end point // press down the stepheight @@ -1994,8 +2001,8 @@ void PM_Duck( void ) int buttonsChanged = ( pmove->oldbuttons ^ pmove->cmd.buttons ); // These buttons have changed this frame int nButtonPressed = buttonsChanged & pmove->cmd.buttons; // The changed ones still down are "pressed" - int duckchange = buttonsChanged & IN_DUCK ? 1 : 0; - int duckpressed = nButtonPressed & IN_DUCK ? 1 : 0; + //int duckchange = buttonsChanged & IN_DUCK ? 1 : 0; + //int duckpressed = nButtonPressed & IN_DUCK ? 1 : 0; if( pmove->cmd.buttons & IN_DUCK ) { @@ -2261,6 +2268,7 @@ void PM_AddGravity() pmove->basevelocity[2] = 0; PM_CheckVelocity(); } + /* ============ PM_PushEntity diff --git a/pm_shared/pm_shared.h b/pm_shared/pm_shared.h index 124d37ba..1d0e4f38 100644 --- a/pm_shared/pm_shared.h +++ b/pm_shared/pm_shared.h @@ -16,6 +16,12 @@ #ifndef PM_SHARED_H #define PM_SHARED_H +#ifdef _WIN32 +#ifndef __MINGW32__ +#pragma once +#endif /* not __MINGW32__ */ +#endif + void PM_Init( struct playermove_s *ppmove ); void PM_Move( struct playermove_s *ppmove, int server ); char PM_FindTextureType( char *name ); From d20c4ff32980ad5cfd999533165ed2f90a61075e Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 02:36:56 +0500 Subject: [PATCH 011/211] Fix build. --- cl_dll/cl_util.h | 10 +++++++--- cl_dll/com_weapons.cpp | 2 +- cl_dll/hud_redraw.cpp | 2 +- cl_dll/text_message.cpp | 12 ++++++------ dlls/buttons.cpp | 2 +- dlls/combat.cpp | 2 +- dlls/weapons.cpp | 2 +- dlls/weapons.h | 2 +- engine/cdll_int.h | 2 +- 9 files changed, 20 insertions(+), 16 deletions(-) diff --git a/cl_dll/cl_util.h b/cl_dll/cl_util.h index 54dcede0..22555caa 100644 --- a/cl_dll/cl_util.h +++ b/cl_dll/cl_util.h @@ -94,8 +94,12 @@ inline void DrawSetTextColor( float r, float g, float b ) inline int SPR_Height( HSPRITE x, int f ) { return gEngfuncs.pfnSPR_Height(x, f); } inline int SPR_Width( HSPRITE x, int f ) { return gEngfuncs.pfnSPR_Width(x, f); } -inline client_textmessage_t *TextMessageGet( const char *pName ) { return gEngfuncs.pfnTextMessageGet( pName ); } -inline int TextMessageDrawChar( int x, int y, int number, int r, int g, int b ) +inline client_textmessage_t *TextMessageGet( const char *pName ) +{ + return gEngfuncs.pfnTextMessageGet( pName ); +} + +inline int TextMessageDrawChar( int x, int y, int number, int r, int g, int b ) { return gEngfuncs.pfnDrawCharacter( x, y, number, r, g, b ); } @@ -115,7 +119,7 @@ inline void GetConsoleStringSize( const char *string, int *width, int *height ) gEngfuncs.pfnDrawConsoleStringLen( (char*)string, width, height ); } -int DrawUtfString( int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b ); +int DrawUtfString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int g, int b ); inline int ConsoleStringLen( const char *string ) { diff --git a/cl_dll/com_weapons.cpp b/cl_dll/com_weapons.cpp index e50de419..774df091 100644 --- a/cl_dll/com_weapons.cpp +++ b/cl_dll/com_weapons.cpp @@ -46,7 +46,7 @@ void COM_Log( const char *pszFile, const char *fmt, ... ) va_list argptr; char string[1024]; FILE *fp; - char *pfilename; + const char *pfilename; if( !pszFile ) { diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index 5182b484..829fd4b2 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -281,7 +281,7 @@ int CHud::DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r int CHud::DrawHudStringReverse( int xpos, int ypos, int iMinX, const char *szString, int r, int g, int b ) { // find the end of the string - for( char *szIt = szString; *szIt != 0; szIt++ ) + for( const char *szIt = szString; *szIt != 0; szIt++ ) xpos -= gHUD.m_scrinfo.charWidths[(unsigned char)*szIt]; if( xpos < iMinX ) xpos = iMinX; diff --git a/cl_dll/text_message.cpp b/cl_dll/text_message.cpp index 13b62577..58dae6f7 100644 --- a/cl_dll/text_message.cpp +++ b/cl_dll/text_message.cpp @@ -45,7 +45,7 @@ int CHudTextMessage::Init( void ) char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size ) { char *dst = dst_buffer; - for( char *src = msg; *src != 0 && buffer_size > 0; buffer_size-- ) + for( char *src = (char*)msg; *src != 0 && buffer_size > 0; buffer_size-- ) { if( *src == '#' ) { @@ -163,22 +163,22 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf int msg_dest = READ_BYTE(); static char szBuf[6][128]; - char *msg_text = LookupString( READ_STRING(), &msg_dest ); + const char *msg_text = LookupString( READ_STRING(), &msg_dest ); msg_text = strcpy( szBuf[0], msg_text ); // keep reading strings and using C format strings for subsituting the strings into the localised text string const char *sstr1 = LookupString( READ_STRING() ); sstr1 = strcpy( szBuf[1], sstr1 ); - StripEndNewlineFromString( sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines + StripEndNewlineFromString( (char*)sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines const char *sstr2 = LookupString( READ_STRING() ); sstr2 = strcpy( szBuf[2], sstr2 ); - StripEndNewlineFromString( sstr2 ); + StripEndNewlineFromString( (char*)sstr2 ); const char *sstr3 = LookupString( READ_STRING() ); sstr3 = strcpy( szBuf[3], sstr3 ); - StripEndNewlineFromString( sstr3 ); + StripEndNewlineFromString( (char*)sstr3 ); const char *sstr4 = LookupString( READ_STRING() ); sstr4 = strcpy( szBuf[4], sstr4 ); - StripEndNewlineFromString( sstr4 ); + StripEndNewlineFromString( (char*)sstr4 ); char *psz = szBuf[5]; switch( msg_dest ) diff --git a/dlls/buttons.cpp b/dlls/buttons.cpp index 76f4ad91..df7c51f3 100644 --- a/dlls/buttons.cpp +++ b/dlls/buttons.cpp @@ -525,7 +525,7 @@ void CBaseButton::Spawn() // Button sound table. // Also used by CBaseDoor to get 'touched' door lock/unlock sounds -char *ButtonSound( int sound ) +const char *ButtonSound( int sound ) { const char *pszSound; diff --git a/dlls/combat.cpp b/dlls/combat.cpp index d8830c20..35e4ffcf 100644 --- a/dlls/combat.cpp +++ b/dlls/combat.cpp @@ -1463,7 +1463,7 @@ void CBaseEntity::FireBullets( ULONG cShots, Vector vecSrc, Vector vecDirShootin } } // make bullet trails - UTIL_BubbleTrail( vecSrc, tr.vecEndPos, (int)( ( flDistance * tr.flFraction ) / 64.0 ); + UTIL_BubbleTrail( vecSrc, tr.vecEndPos, (int)( ( flDistance * tr.flFraction ) / 64.0 ) ); } ApplyMultiDamage( pev, pevAttacker ); } diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 0b6f7de6..989c32a8 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -935,7 +935,7 @@ BOOL CBasePlayerWeapon::CanDeploy( void ) return TRUE; } -BOOL CBasePlayerWeapon::DefaultDeploy( const char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal /* = 0 */, int body ) +BOOL CBasePlayerWeapon::DefaultDeploy( const char *szViewModel, const char *szWeaponModel, int iAnim, const char *szAnimExt, int skiplocal /* = 0 */, int body ) { if( !CanDeploy() ) return FALSE; diff --git a/dlls/weapons.h b/dlls/weapons.h index 8d60bad8..7bb1b486 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -310,7 +310,7 @@ public: virtual BOOL CanDeploy( void ); virtual BOOL IsUseable( void ); - BOOL DefaultDeploy( const char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal = 0, int body = 0 ); + BOOL DefaultDeploy( const char *szViewModel, const char *szWeaponModel, int iAnim, const char *szAnimExt, int skiplocal = 0, int body = 0 ); int DefaultReload( int iClipSize, int iAnim, float fDelay, int body = 0 ); virtual void ItemPostFrame( void ); // called each frame by the player PostThink diff --git a/engine/cdll_int.h b/engine/cdll_int.h index a0dc59c2..056146b4 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -205,7 +205,7 @@ typedef struct cl_enginefuncs_s int (*CL_CreateVisibleEntity)( int type, struct cl_entity_s *ent ); const struct model_s* (*GetSpritePointer)( HSPRITE hSprite ); - void (*pfnPlaySoundByNameAtLocation)( char *szSound, float volume, float *origin ); + void (*pfnPlaySoundByNameAtLocation)( const char *szSound, float volume, float *origin ); unsigned short (*pfnPrecacheEvent)( int type, const char* psz ); void (*pfnPlaybackEvent)( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); From c28d86f748362565baa82a522404e1ae7476fac8 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 02:42:30 +0500 Subject: [PATCH 012/211] Fix wrong check. --- dlls/cbase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/cbase.cpp b/dlls/cbase.cpp index 0cc10bdb..cdf9a00f 100644 --- a/dlls/cbase.cpp +++ b/dlls/cbase.cpp @@ -511,7 +511,7 @@ int CBaseEntity::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, fl // (that is, no actual entity projectile was involved in the attack so use the shooter's origin). if( pevAttacker == pevInflictor ) { - vecTemp = pevInflictor->origin - VecBModelOrigin( pev ); + vecTemp = pevAttacker->origin - VecBModelOrigin( pev ); } else // an actual missile was involved. From 4ae58b4170bc0f05e27baea53262ccbfc22e7fd4 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 05:37:14 +0500 Subject: [PATCH 013/211] Fix weapon reload bug. Use macros instead of magic numbers. --- dlls/crossbow.cpp | 4 ++-- dlls/egon.cpp | 2 +- dlls/glock.cpp | 8 ++++---- dlls/python.cpp | 4 ++-- dlls/rpg.cpp | 9 ++------- dlls/shotgun.cpp | 2 +- 6 files changed, 12 insertions(+), 17 deletions(-) diff --git a/dlls/crossbow.cpp b/dlls/crossbow.cpp index d749c785..12d0ff8c 100644 --- a/dlls/crossbow.cpp +++ b/dlls/crossbow.cpp @@ -481,7 +481,7 @@ void CCrossbow::SecondaryAttack() void CCrossbow::Reload( void ) { - if( m_pPlayer->ammo_bolts <= 0 ) + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == CROSSBOW_MAX_CLIP ) return; if( m_pPlayer->pev->fov != 0 ) @@ -489,7 +489,7 @@ void CCrossbow::Reload( void ) SecondaryAttack(); } - if( DefaultReload( 5, CROSSBOW_RELOAD, 4.5 ) ) + if( DefaultReload( CROSSBOW_MAX_CLIP, CROSSBOW_RELOAD, 4.5 ) ) { EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/xbow_reload1.wav", RANDOM_FLOAT( 0.95, 1.0 ), ATTN_NORM, 0, 93 + RANDOM_LONG( 0, 0xF ) ); } diff --git a/dlls/egon.cpp b/dlls/egon.cpp index 9a4de49b..b83c9086 100644 --- a/dlls/egon.cpp +++ b/dlls/egon.cpp @@ -143,7 +143,7 @@ float CEgon::GetDischargeInterval( void ) BOOL CEgon::HasAmmo( void ) { - if( m_pPlayer->ammo_uranium <= 0 ) + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) return FALSE; return TRUE; diff --git a/dlls/glock.cpp b/dlls/glock.cpp index 1f4517e7..4e679750 100644 --- a/dlls/glock.cpp +++ b/dlls/glock.cpp @@ -169,15 +169,15 @@ void CGlock::GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim ) void CGlock::Reload( void ) { - if( m_pPlayer->ammo_9mm <= 0 ) - return; + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == GLOCK_MAX_CLIP ) + return; int iResult; if( m_iClip == 0 ) - iResult = DefaultReload( 17, GLOCK_RELOAD, 1.5 ); + iResult = DefaultReload( GLOCK_MAX_CLIP, GLOCK_RELOAD, 1.5 ); else - iResult = DefaultReload( 17, GLOCK_RELOAD_NOT_EMPTY, 1.5 ); + iResult = DefaultReload( GLOCK_MAX_CLIP, GLOCK_RELOAD_NOT_EMPTY, 1.5 ); if( iResult ) { diff --git a/dlls/python.cpp b/dlls/python.cpp index 7bb71325..b7e48386 100644 --- a/dlls/python.cpp +++ b/dlls/python.cpp @@ -212,7 +212,7 @@ void CPython::PrimaryAttack() void CPython::Reload( void ) { - if( m_pPlayer->ammo_357 <= 0 ) + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == PYTHON_MAX_CLIP ) return; if( m_pPlayer->pev->fov != 0 ) @@ -227,7 +227,7 @@ void CPython::Reload( void ) #else bUseScope = g_pGameRules->IsMultiplayer(); #endif - if( DefaultReload( 6, PYTHON_RELOAD, 2.0, bUseScope ) ) + if( DefaultReload( PYTHON_MAX_CLIP, PYTHON_RELOAD, 2.0, bUseScope ) ) { m_flSoundDelay = 1.5; } diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index 95c9132a..fb2b39c8 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -278,13 +278,8 @@ void CRpg::Reload( void ) { int iResult = 0; - if( m_iClip == 1 ) - { - // don't bother with any of this if don't need to reload. - return; - } - - if( m_pPlayer->ammo_rockets <= 0 ) + // don't bother with any of this if don't need to reload. + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == RPG_MAX_CLIP ) return; // because the RPG waits to autoreload when no missiles are active while the LTD is on, the diff --git a/dlls/shotgun.cpp b/dlls/shotgun.cpp index 595561e2..d6be007a 100644 --- a/dlls/shotgun.cpp +++ b/dlls/shotgun.cpp @@ -320,7 +320,7 @@ void CShotgun::WeaponIdle( void ) } else if( m_fInSpecialReload != 0 ) { - if( m_iClip != 8 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ) + if( m_iClip != SHOTGUN_MAX_CLIP && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ) { Reload(); } From cabb03ad45de13063b0dc42255455d1eaab22eda Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 16:11:40 +0500 Subject: [PATCH 014/211] Merge https://github.com/ValveSoftware/halflife/pull/1598/commits/2257fa14e7b1cd1fffd0c9d058b7368799b8b2a3 --- dlls/hornet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/hornet.cpp b/dlls/hornet.cpp index d968b79b..758ba7e9 100644 --- a/dlls/hornet.cpp +++ b/dlls/hornet.cpp @@ -407,7 +407,7 @@ void CHornet::DartTouch( CBaseEntity *pOther ) void CHornet::DieTouch( CBaseEntity *pOther ) { - if( pOther && pOther->pev->takedamage ) + if( pOther && pOther->pev->takedamage && pev->owner ) { // do the damage switch( RANDOM_LONG( 0, 2 ) ) From 7113204d5133ed67975bd9220fe50b6ae8b1fda9 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 16:42:54 +0500 Subject: [PATCH 015/211] Merge https://github.com/ValveSoftware/halflife/pull/1600/commits/8903b33ef34cbe7e33bfbaa15f5c418bf9d01a02 --- dlls/crowbar.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index 00b16d57..051d2309 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -220,8 +220,14 @@ int CCrowbar::Swing( int fFirst ) CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit ); ClearMultiDamage(); - + // If building with the clientside weapon prediction system, + // UTIL_WeaponTimeBase() is always 0 and m_flNextPrimaryAttack is >= -1.0f, thus making + // m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() always evaluate to false. +#ifdef CLIENT_WEAPONS + if( ( m_flNextPrimaryAttack + 1 == UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() ) +#else if( ( m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() ) +#endif { // first swing does full damage pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB ); From 13a691bdd85c692da49eb66cc1ea04cedd012950 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 19:02:52 +0500 Subject: [PATCH 016/211] Fix GetHullBounds() Same as in https://github.com/FWGS/cs16-client/commit/8d4515be429bfbff90b702d968ea9d57690b9ef4 --- cl_dll/cdll_int.cpp | 12 ++++++------ dlls/client.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index 13200a89..ffd342d2 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -76,18 +76,18 @@ int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ) switch( hullnumber ) { case 0: // Normal player - mins = Vector( -16, -16, -36 ); - maxs = Vector( 16, 16, 36 ); + Vector( -16, -16, -36 ).CopyToArray(mins); + Vector( 16, 16, 36 ).CopyToArray(maxs); iret = 1; break; case 1: // Crouched player - mins = Vector( -16, -16, -18 ); - maxs = Vector( 16, 16, 18 ); + Vector( -16, -16, -18 ).CopyToArray(mins); + Vector( 16, 16, 18 ).CopyToArray(maxs); iret = 1; break; case 2: // Point based hull - mins = Vector( 0, 0, 0 ); - maxs = Vector( 0, 0, 0 ); + Vector( 0, 0, 0 ).CopyToArray(mins); + Vector( 0, 0, 0 ).CopyToArray(maxs); iret = 1; break; } diff --git a/dlls/client.cpp b/dlls/client.cpp index 99f1913b..ea4eb590 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -1853,18 +1853,18 @@ int GetHullBounds( int hullnumber, float *mins, float *maxs ) switch( hullnumber ) { case 0: // Normal player - mins = VEC_HULL_MIN; - maxs = VEC_HULL_MAX; + VEC_HULL_MIN.CopyToArray(mins); + VEC_HULL_MAX.CopyToArray(maxs); iret = 1; break; case 1: // Crouched player - mins = VEC_DUCK_HULL_MIN; - maxs = VEC_DUCK_HULL_MAX; + VEC_DUCK_HULL_MIN.CopyToArray(mins); + VEC_DUCK_HULL_MAX.CopyToArray(maxs); iret = 1; break; case 2: // Point based hull - mins = Vector( 0, 0, 0 ); - maxs = Vector( 0, 0, 0 ); + Vector( 0, 0, 0 ).CopyToArray(mins); + Vector( 0, 0, 0 ).CopyToArray(maxs); iret = 1; break; } From 3dfbd2a41f550b39acc382bac1bf436504577143 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 19:31:49 +0500 Subject: [PATCH 017/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/14fa5e81d0c327d3e2b43d2804b6c9377ce96ec4 --- dlls/world.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dlls/world.cpp b/dlls/world.cpp index f352bd52..1cc645c9 100644 --- a/dlls/world.cpp +++ b/dlls/world.cpp @@ -484,9 +484,12 @@ void CWorld::Precache( void ) ///!!!LATER - do we want a sound ent in deathmatch? (sjb) //pSoundEnt = CBaseEntity::Create( "soundent", g_vecZero, g_vecZero, edict() ); pSoundEnt = GetClassPtr( ( CSoundEnt *)NULL ); - pSoundEnt->Spawn(); - if( !pSoundEnt ) + if( pSoundEnt ) + { + pSoundEnt->Spawn(); + } + else { ALERT ( at_console, "**COULD NOT CREATE SOUNDENT**\n" ); } From ac6d7c4384d12ce7ff59162db892139fc91109c1 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 19:35:16 +0500 Subject: [PATCH 018/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/5cade5b7607da186349ad4c49fd778cff40ea3ee --- dlls/monsters.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index cfe4c561..5f112a62 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -334,12 +334,10 @@ void CBaseMonster::Look( int iDistance ) { if( pev->spawnflags & SF_MONSTER_WAIT_TILL_SEEN ) { - CBaseMonster *pClient; - - pClient = pSightEnt->MyMonsterPointer(); + CBaseMonster *pClient = pSightEnt->MyMonsterPointer(); // don't link this client in the list if the monster is wait till seen and the player isn't facing the monster - if( pSightEnt && !pClient->FInViewCone( this ) ) + if( pClient && !pClient->FInViewCone( this ) ) { // we're not in the player's view cone. continue; From d3ebe0ac46aedfd75a4ccafadfd70e3665361ac5 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 19:52:18 +0500 Subject: [PATCH 019/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/e7b5c6be5153ac402fc771d164808d2752105299 --- dlls/bigmomma.cpp | 2 +- dlls/crowbar.cpp | 44 ++++++++++++++++++++++---------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/dlls/bigmomma.cpp b/dlls/bigmomma.cpp index a038c776..6b594983 100644 --- a/dlls/bigmomma.cpp +++ b/dlls/bigmomma.cpp @@ -411,7 +411,7 @@ void CBigMomma::SetYawSpeed( void ) { int ys; - switch ( m_Activity ) + switch( m_Activity ) { case ACT_IDLE: ys = 100; diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index 051d2309..b00a0ad3 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -219,32 +219,32 @@ int CCrowbar::Swing( int fFirst ) fDidHit = TRUE; CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit ); - ClearMultiDamage(); - // If building with the clientside weapon prediction system, - // UTIL_WeaponTimeBase() is always 0 and m_flNextPrimaryAttack is >= -1.0f, thus making - // m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() always evaluate to false. -#ifdef CLIENT_WEAPONS - if( ( m_flNextPrimaryAttack + 1 == UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() ) -#else - if( ( m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() ) -#endif - { - // first swing does full damage - pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB ); - } - else - { - // subsequent swings do half - pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgCrowbar / 2, gpGlobals->v_forward, &tr, DMG_CLUB ); - } - ApplyMultiDamage( m_pPlayer->pev, m_pPlayer->pev ); - // play thwack, smack, or dong sound - float flVol = 1.0; - int fHitWorld = TRUE; + float flVol = 1.0; + int fHitWorld = TRUE; if( pEntity ) { + ClearMultiDamage(); + // If building with the clientside weapon prediction system, + // UTIL_WeaponTimeBase() is always 0 and m_flNextPrimaryAttack is >= -1.0f, thus making + // m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() always evaluate to false. +#ifdef CLIENT_WEAPONS + if( ( m_flNextPrimaryAttack + 1 == UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() ) +#else + if( ( m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase() ) || g_pGameRules->IsMultiplayer() ) +#endif + { + // first swing does full damage + pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB ); + } + else + { + // subsequent swings do half + pEntity->TraceAttack( m_pPlayer->pev, gSkillData.plrDmgCrowbar / 2, gpGlobals->v_forward, &tr, DMG_CLUB ); + } + ApplyMultiDamage( m_pPlayer->pev, m_pPlayer->pev ); + if( pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE ) { // play thwack or smack sound From 391c2aa2175d8e5511d80f68bac6d4b511739ca6 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 20:09:34 +0500 Subject: [PATCH 020/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/5a13e06f522b1aff363fd0b1d360c2ed725cc6e4 --- dlls/aflock.cpp | 6 +++--- dlls/client.cpp | 2 +- dlls/plats.cpp | 24 +++++++++++++----------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/dlls/aflock.cpp b/dlls/aflock.cpp index 19998a9d..d50a8165 100644 --- a/dlls/aflock.cpp +++ b/dlls/aflock.cpp @@ -839,11 +839,11 @@ void CFlockingFlyer::SquadRemove( CFlockingFlyer *pRemove ) { CFlockingFlyer *pLeader = m_pSquadNext; - // copy the enemy LKP to the new leader - pLeader->m_vecEnemyLKP = m_vecEnemyLKP; - if( pLeader ) { + // copy the enemy LKP to the new leader + pLeader->m_vecEnemyLKP = m_vecEnemyLKP; + CFlockingFlyer *pList = pLeader; while( pList ) diff --git a/dlls/client.cpp b/dlls/client.cpp index ea4eb590..5d41d6ad 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -353,7 +353,7 @@ void Host_Say( edict_t *pEntity, int teamonly ) } // remove quotes if present - if( *p == '"' ) + if( p && *p == '"' ) { p++; p[strlen( p ) - 1] = 0; diff --git a/dlls/plats.cpp b/dlls/plats.cpp index 8fecf684..203f5d9b 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -743,21 +743,21 @@ void CFuncTrain::Next( void ) pev->target = pTarg->pev->target; m_flWait = pTarg->GetDelay(); - if ( m_pevCurrentTarget && m_pevCurrentTarget->speed != 0 ) + if( m_pevCurrentTarget && m_pevCurrentTarget->speed != 0 ) { // don't copy speed from target if it is 0 (uninitialized) pev->speed = m_pevCurrentTarget->speed; - ALERT( at_aiconsole, "Train %s speed to %4.2f\n", STRING(pev->targetname), pev->speed ); + ALERT( at_aiconsole, "Train %s speed to %4.2f\n", STRING( pev->targetname ), pev->speed ); } m_pevCurrentTarget = pTarg->pev;// keep track of this since path corners change our target for us. pev->enemy = pTarg->edict();//hack - if(FBitSet(m_pevCurrentTarget->spawnflags, SF_CORNER_TELEPORT)) + if( FBitSet( m_pevCurrentTarget->spawnflags, SF_CORNER_TELEPORT ) ) { // Path corner has indicated a teleport to the next corner. - SetBits(pev->effects, EF_NOINTERP); - UTIL_SetOrigin(pev, pTarg->pev->origin - (pev->mins + pev->maxs)* 0.5); + SetBits( pev->effects, EF_NOINTERP ); + UTIL_SetOrigin( pev, pTarg->pev->origin - ( pev->mins + pev->maxs ) * 0.5 ); Wait(); // Get on with doing the next path corner. } else @@ -767,13 +767,15 @@ void CFuncTrain::Next( void ) // CHANGED this from CHAN_VOICE to CHAN_STATIC around OEM beta time because trains should // use CHAN_STATIC for their movement sounds to prevent sound field problems. // this is not a hack or temporary fix, this is how things should be. (sjb). - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - if ( pev->noiseMovement ) - EMIT_SOUND (ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement), m_volume, ATTN_NORM); - ClearBits(pev->effects, EF_NOINTERP); + if( pev->noiseMovement ) + { + STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING( pev->noiseMovement ) ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); + } + + ClearBits( pev->effects, EF_NOINTERP ); SetMoveDone( &CFuncTrain::Wait ); - LinearMove (pTarg->pev->origin - (pev->mins + pev->maxs)* 0.5, pev->speed); + LinearMove( pTarg->pev->origin - ( pev->mins + pev->maxs )* 0.5, pev->speed ); } } From 98a562c20e2add40c34973ed1be95f167120c10f Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 2 Jul 2017 21:17:51 +0500 Subject: [PATCH 021/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/9d2ae368aae3207dc9f66aca8a3c1505d5c3014a --- dlls/scientist.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dlls/scientist.cpp b/dlls/scientist.cpp index d7659c61..7cf9cc4d 100644 --- a/dlls/scientist.cpp +++ b/dlls/scientist.cpp @@ -464,7 +464,10 @@ void CScientist::StartTask( Task_t *pTask ) { Talk( 2 ); m_hTalkTarget = m_hEnemy; - if( m_hEnemy->IsPlayer() ) + + //The enemy can be null here. - Solokiller + //Discovered while testing the barnacle grapple on headcrabs with scientists in view. + if( m_hEnemy && m_hEnemy->IsPlayer() ) PlaySentence( "SC_PLFEAR", 5, VOL_NORM, ATTN_NORM ); else PlaySentence( "SC_FEAR", 5, VOL_NORM, ATTN_NORM ); From 4800c0d54ca8a9c5de8e0aa2b2f448b7c8b164ff Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 3 Jul 2017 03:24:14 +0500 Subject: [PATCH 022/211] Deactivate satchels on disconnect. --- dlls/client.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/dlls/client.cpp b/dlls/client.cpp index 5d41d6ad..7354f68f 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -110,14 +110,12 @@ void ClientDisconnect( edict_t *pEntity ) WRITE_STRING( text ); MESSAGE_END(); - CSound *pSound; - pSound = CSoundEnt::SoundPointerForIndex( CSoundEnt::ClientSoundIndex( pEntity ) ); + CSound *pSound = CSoundEnt::SoundPointerForIndex( CSoundEnt::ClientSoundIndex( pEntity ) ); + + // since this client isn't around to think anymore, reset their sound. + if( pSound ) { - // since this client isn't around to think anymore, reset their sound. - if( pSound ) - { - pSound->Reset(); - } + pSound->Reset(); } // since the edict doesn't get deleted, fix it so it doesn't interfere. @@ -125,6 +123,12 @@ void ClientDisconnect( edict_t *pEntity ) pEntity->v.solid = SOLID_NOT;// nonsolid UTIL_SetOrigin( &pEntity->v, pEntity->v.origin ); + CBasePlayer *pl = (CBasePlayer *)CBaseEntity::Instance( pEntity ); + if( pl->HasNamedPlayerItem( "weapon_satchel" ) ) + { + DeactivateSatchels( pl ); + } + g_pGameRules->ClientDisconnected( pEntity ); } From 780b4616fe420f3d9ab24d68bcc51ab172e4b1d0 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 02:41:23 +0500 Subject: [PATCH 023/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/c98747a35e324dca2d88c13036f1f74947caba96 --- dlls/rpg.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index fb2b39c8..021ad534 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -460,6 +460,8 @@ void CRpg::PrimaryAttack() m_flNextPrimaryAttack = GetNextAttackDelay( 1.5 ); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.5; + + ResetEmptySound(); } else { @@ -487,13 +489,13 @@ void CRpg::WeaponIdle( void ) { UpdateSpot(); - ResetEmptySound(); - if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() ) return; if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ) { + ResetEmptySound(); + int iAnim; float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 ); if( flRand <= 0.75 || m_fSpotActive ) From 2cb20f7b7556306d08306e6615a93bf5d4f25a7a Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 02:43:50 +0500 Subject: [PATCH 024/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/274bd297f9af9cc251447dafc97de26019f0ed20 --- dlls/python.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/python.cpp b/dlls/python.cpp index b7e48386..90606c50 100644 --- a/dlls/python.cpp +++ b/dlls/python.cpp @@ -169,7 +169,7 @@ void CPython::PrimaryAttack() Reload(); else { - EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "weapons/357_cock1.wav", 0.8, ATTN_NORM ); + PlayEmptySound(); m_flNextPrimaryAttack = 0.15; } From c4820ad0df7bda569275452ad8f25c60d00301f9 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 03:12:53 +0500 Subject: [PATCH 025/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/89efd616d6aed0304db5bf63bfecd311c1cedbdd --- dlls/subs.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dlls/subs.cpp b/dlls/subs.cpp index 5ebe757b..4654363a 100644 --- a/dlls/subs.cpp +++ b/dlls/subs.cpp @@ -107,6 +107,13 @@ void CBaseEntity::UpdateOnRemove( void ) if( pev->globalname ) gGlobalState.EntitySetState( pev->globalname, GLOBAL_DEAD ); + + // tell owner ( if any ) that we're dead.This is mostly for MonsterMaker functionality. + //Killtarget didn't do this before, so the counter broke. - Solokiller + if( CBaseEntity* pOwner = pev->owner ? Instance( pev->owner ) : 0 ) + { + pOwner->DeathNotice( this ); + } } // Convenient way to delay removing oneself From f22f1331afc052a70921e3bb0421c7c205a14bb2 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 03:25:39 +0500 Subject: [PATCH 026/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/2219190a09711ecbb441ec7160315eccac194dea --- dlls/controller.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/dlls/controller.cpp b/dlls/controller.cpp index bfa119d3..b042949e 100644 --- a/dlls/controller.cpp +++ b/dlls/controller.cpp @@ -47,6 +47,7 @@ public: void Spawn( void ); void Precache( void ); + void UpdateOnRemove(); void SetYawSpeed( void ); int Classify( void ); void HandleAnimEvent( MonsterEvent_t *pEvent ); @@ -384,6 +385,23 @@ void CController::Precache() UTIL_PrecacheOther( "controller_head_ball" ); } +void CController::UpdateOnRemove() +{ + CBaseEntity::UpdateOnRemove(); + + if( m_pBall[0] ) + { + UTIL_Remove( m_pBall[0] ); + m_pBall[0] = nullptr; + } + + if( m_pBall[1] ) + { + UTIL_Remove( m_pBall[1] ); + m_pBall[1] = nullptr; + } +} + //========================================================= // AI Schedules Specific to this monster //========================================================= From 6379954153e2c0c0001139b7f7dce9835b17da15 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 03:32:53 +0500 Subject: [PATCH 027/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/e41b164fdffef1b89aa5286ae15c9617dfcf2188 https://github.com/SamVanheer/HLEnhanced/commit/2da0a12d353f2078f1e2f6d931deb9c0f04e5b43 --- dlls/gargantua.cpp | 14 ++++++++++++++ dlls/islave.cpp | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/dlls/gargantua.cpp b/dlls/gargantua.cpp index 7f60b401..6aa6a738 100644 --- a/dlls/gargantua.cpp +++ b/dlls/gargantua.cpp @@ -200,6 +200,7 @@ class CGargantua : public CBaseMonster public: void Spawn( void ); void Precache( void ); + void UpdateOnRemove(); void SetYawSpeed( void ); int Classify( void ); int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); @@ -802,6 +803,19 @@ void CGargantua::Precache() PRECACHE_SOUND( (char *)pBreatheSounds[i] ); } +void CGargantua::UpdateOnRemove() +{ + CBaseEntity::UpdateOnRemove(); + + if( m_pEyeGlow ) + { + UTIL_Remove( m_pEyeGlow ); + m_pEyeGlow = 0; + } + + FlameDestroy(); +} + void CGargantua::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ) { ALERT( at_aiconsole, "CGargantua::TraceAttack\n" ); diff --git a/dlls/islave.cpp b/dlls/islave.cpp index 3b4343d3..51def5d3 100644 --- a/dlls/islave.cpp +++ b/dlls/islave.cpp @@ -44,6 +44,7 @@ class CISlave : public CSquadMonster public: void Spawn( void ); void Precache( void ); + void UpdateOnRemove(); void SetYawSpeed( void ); int ISoundMask( void ); int Classify( void ); @@ -557,6 +558,13 @@ void CISlave::Precache() UTIL_PrecacheOther( "test_effect" ); } +void CISlave::UpdateOnRemove() +{ + CBaseEntity::UpdateOnRemove(); + + ClearBeams(); +} + //========================================================= // TakeDamage - get provoked when injured //========================================================= From 95d81733fcc5cb152d9b71224fe4a60de52263bc Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 03:41:48 +0500 Subject: [PATCH 028/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/29947a0558967e43ead0c4558251c6f77924b3ea --- dlls/tripmine.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dlls/tripmine.cpp b/dlls/tripmine.cpp index 520206dd..60190604 100644 --- a/dlls/tripmine.cpp +++ b/dlls/tripmine.cpp @@ -43,6 +43,7 @@ class CTripmineGrenade : public CGrenade { void Spawn( void ); void Precache( void ); + void UpdateOnRemove(); virtual int Save( CSave &save ); virtual int Restore( CRestore &restore ); @@ -148,6 +149,13 @@ void CTripmineGrenade::Precache( void ) PRECACHE_SOUND( "weapons/mine_charge.wav" ); } +void CTripmineGrenade::UpdateOnRemove() +{ + CBaseEntity::UpdateOnRemove(); + + KillBeam(); +} + void CTripmineGrenade::WarningThink( void ) { // play warning sound From 9c85e5eb77e81b642836bad53ddeaa72a6284c02 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 03:46:20 +0500 Subject: [PATCH 029/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/b3cf83bbf11e0f098382f27f63d0364043306a03 --- dlls/turret.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dlls/turret.cpp b/dlls/turret.cpp index 5b9e1b77..ae95db14 100644 --- a/dlls/turret.cpp +++ b/dlls/turret.cpp @@ -56,6 +56,7 @@ class CBaseTurret : public CBaseMonster public: void Spawn( void ); virtual void Precache( void ); + void UpdateOnRemove(); void KeyValue( KeyValueData *pkvd ); void EXPORT TurretUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); @@ -279,6 +280,17 @@ void CBaseTurret::Precache() PRECACHE_SOUND( "turret/tu_alert.wav" ); } +void CBaseTurret::UpdateOnRemove() +{ + CBaseEntity::UpdateOnRemove(); + + if( m_pEyeGlow ) + { + UTIL_Remove( m_pEyeGlow ); + m_pEyeGlow = 0; + } +} + #define TURRET_GLOW_SPRITE "sprites/flare3.spr" void CTurret::Spawn() From 9bb5cb2f05391097453a27b51b671044189f320e Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 03:56:48 +0500 Subject: [PATCH 030/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/46ea4af5f8dc168d048b2cada03308e9c4c3069d --- dlls/nihilanth.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dlls/nihilanth.cpp b/dlls/nihilanth.cpp index 479a2b34..82b31e13 100644 --- a/dlls/nihilanth.cpp +++ b/dlls/nihilanth.cpp @@ -34,6 +34,7 @@ public: void Spawn( void ); void Precache( void ); + void UpdateOnRemove(); int Classify( void ) { return CLASS_ALIEN_MILITARY; }; int BloodColor( void ) { return BLOOD_COLOR_YELLOW; } void Killed( entvars_t *pevAttacker, int iGib ); @@ -345,6 +346,26 @@ void CNihilanth::Precache( void ) PRECACHE_SOUND( "debris/beamstart7.wav" ); } +void CNihilanth::UpdateOnRemove() +{ + CBaseEntity::UpdateOnRemove(); + + if( m_pBall ) + { + UTIL_Remove( m_pBall ); + m_pBall = 0; + } + + for( int i = 0; i < N_SPHERES, i++ ) + { + if( CBaseEntity* pSphere = (CBaseEntity *)m_hSphere[i] ) + { + UTIL_Remove( pSphere ); + m_hSphere[i] = 0; + } + } +} + void CNihilanth::PainSound( void ) { if( m_flNextPainSound > gpGlobals->time ) From 3ad3004dd900f5bfaecf2d57bead3e34d2fc5785 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 04:03:22 +0500 Subject: [PATCH 031/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/3e2f7e1e81af06d092f6350e58b26dfeb699ebc6 --- dlls/controller.cpp | 4 ++-- dlls/crowbar.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dlls/controller.cpp b/dlls/controller.cpp index b042949e..e1d57517 100644 --- a/dlls/controller.cpp +++ b/dlls/controller.cpp @@ -392,13 +392,13 @@ void CController::UpdateOnRemove() if( m_pBall[0] ) { UTIL_Remove( m_pBall[0] ); - m_pBall[0] = nullptr; + m_pBall[0] = 0; } if( m_pBall[1] ) { UTIL_Remove( m_pBall[1] ); - m_pBall[1] = nullptr; + m_pBall[1] = 0; } } diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index b00a0ad3..65e21162 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -139,8 +139,10 @@ void CCrowbar::PrimaryAttack() { if( !Swing( 1 ) ) { +#ifndef CLIENT_DLL SetThink( &CCrowbar::SwingAgain ); pev->nextthink = gpGlobals->time + 0.1; +#endif } } @@ -301,11 +303,11 @@ int CCrowbar::Swing( int fFirst ) } m_pPlayer->m_iWeaponVolume = (int)( flVol * CROWBAR_WALLHIT_VOLUME ); -#endif - m_flNextPrimaryAttack = GetNextAttackDelay( 0.25 ); SetThink( &CCrowbar::Smack ); pev->nextthink = UTIL_WeaponTimeBase() + 0.2; +#endif + m_flNextPrimaryAttack = GetNextAttackDelay( 0.25 ); } return fDidHit; } From 740a5a2c31b799dd3f8bd4e5312451489e3cafbe Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 16:42:08 +0500 Subject: [PATCH 032/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/2baa8fe118db844968b2868d378d93b9f7f4f742 --- dlls/weapons.cpp | 7 +++++++ dlls/weapons.h | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 989c32a8..854425ad 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -1557,6 +1557,13 @@ TYPEDESCRIPTION CEgon::m_SaveData[] = IMPLEMENT_SAVERESTORE( CEgon, CBasePlayerWeapon ) +TYPEDESCRIPTION CHgun::m_SaveData[] = +{ + DEFINE_FIELD( CHgun, m_flRechargeTime, FIELD_FLOAT ), +}; + +IMPLEMENT_SAVERESTORE( CHgun, CBasePlayerWeapon ) + TYPEDESCRIPTION CSatchel::m_SaveData[] = { DEFINE_FIELD( CSatchel, m_chargeReady, FIELD_INTEGER ), diff --git a/dlls/weapons.h b/dlls/weapons.h index 7bb1b486..6f5de37a 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -841,6 +841,11 @@ private: class CHgun : public CBasePlayerWeapon { public: +#ifndef CLIENT_DLL + int Save( CSave &save ); + int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; +#endif void Spawn( void ); void Precache( void ); int iItemSlot( void ) { return 4; } From 4024c29caf23984191d601bce7e17c5276b83632 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 16:45:48 +0500 Subject: [PATCH 033/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/7002f8fb477c03b44ec2251b1308f4e5432cb50e --- cl_dll/ammo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index 860cde42..3d214280 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -542,7 +542,7 @@ int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) } else { - if ( m_pWeapon ) + if( m_pWeapon ) SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 ); } @@ -574,6 +574,8 @@ int CHudAmmo::MsgFunc_CurWeapon( const char *pszName, int iSize, void *pbuf ) if( iId < 1 ) { SetCrosshair( 0, nullrc, 0, 0, 0 ); + // Clear out the weapon so we don't keep drawing the last active weapon's ammo. - Solokiller + m_pWeapon = 0; return 0; } From ca7464b158c5ad69c504168cd249dce4135d1a5d Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 16:51:43 +0500 Subject: [PATCH 034/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/60a45fb6cd027168e2c546d64f1176ed830070d8 --- dlls/weapons.cpp | 2 ++ dlls/weapons.h | 1 + 2 files changed, 3 insertions(+) diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 854425ad..ff083ee7 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -598,6 +598,8 @@ BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted ) void CBasePlayerWeapon::ItemPostFrame( void ) { + WeaponTick(); + if( ( m_fInReload ) && ( m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase() ) ) { // complete the reload. diff --git a/dlls/weapons.h b/dlls/weapons.h index 6f5de37a..a7c40678 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -318,6 +318,7 @@ public: virtual void PrimaryAttack( void ) { return; } // do "+ATTACK" virtual void SecondaryAttack( void ) { return; } // do "+ATTACK2" virtual void Reload( void ) { return; } // do "+RELOAD" + virtual void WeaponTick() {} // Always called at beginning of ItemPostFrame. - Solokiller virtual void WeaponIdle( void ) { return; } // called when no buttons pressed virtual int UpdateClientData( CBasePlayer *pPlayer ); // sends hud info to client dll, if things have changed virtual void RetireWeapon( void ); From e5f6f7d9acbc35795cb20cbd7e09bd6e45afd6b9 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 16:58:26 +0500 Subject: [PATCH 035/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/0cbbe099f3170170d41683c2a4288d1f06aad048 --- dlls/shotgun.cpp | 17 ++++++++++------- dlls/weapons.h | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/dlls/shotgun.cpp b/dlls/shotgun.cpp index d6be007a..12e73ede 100644 --- a/dlls/shotgun.cpp +++ b/dlls/shotgun.cpp @@ -169,7 +169,7 @@ void CShotgun::PrimaryAttack() // HEV suit - indicate out of ammo condition m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - if( m_iClip != 0 ) + //if( m_iClip != 0 ) m_flPumpTime = gpGlobals->time + 0.5; m_flNextPrimaryAttack = GetNextAttackDelay( 0.75 ); @@ -240,7 +240,7 @@ void CShotgun::SecondaryAttack( void ) // HEV suit - indicate out of ammo condition m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - if( m_iClip != 0 ) + //if( m_iClip != 0 ) m_flPumpTime = gpGlobals->time + 0.95; m_flNextPrimaryAttack = GetNextAttackDelay( 1.5 ); @@ -299,18 +299,21 @@ void CShotgun::Reload( void ) } } -void CShotgun::WeaponIdle( void ) +void CShotgun::WeaponTick() { - ResetEmptySound(); - - m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); - if( m_flPumpTime && m_flPumpTime < gpGlobals->time ) { // play pumping sound EMIT_SOUND_DYN( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/scock1.wav", 1, ATTN_NORM, 0, 95 + RANDOM_LONG( 0, 0x1f ) ); m_flPumpTime = 0; } +} + +void CShotgun::WeaponIdle( void ) +{ + ResetEmptySound(); + + m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); if( m_flTimeWeaponIdle < UTIL_WeaponTimeBase() ) { diff --git a/dlls/weapons.h b/dlls/weapons.h index a7c40678..7d99e8a6 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -632,6 +632,7 @@ public: void SecondaryAttack( void ); BOOL Deploy( ); void Reload( void ); + void WeaponTick(); void WeaponIdle( void ); int m_fInReload; float m_flNextReload; From 689316912ac98dbd928caacaf73436130e391a28 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 17:06:23 +0500 Subject: [PATCH 036/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/19396936af13e417e7f9eaf48c48c49699da03fb --- cl_dll/ev_hldm.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 787e1be8..381c9179 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -1430,6 +1430,12 @@ void EV_EgonFire( event_args_t *args ) } else { + // If there is any sound playing already, kill it. - Solokiller + // This is necessary because multiple sounds can play on the same channel at the same time. + // In some cases, more than 1 run sound plays when the egon stops firing, in which case only the earliest entry in the list is stopped. + // This ensures no more than 1 of those is ever active at the same time. + gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, EGON_SOUND_RUN ); + if( iFireMode == FIRE_WIDE ) gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, EGON_SOUND_RUN, 0.98, ATTN_NORM, 0, 125 ); else @@ -1438,7 +1444,7 @@ void EV_EgonFire( event_args_t *args ) //Only play the weapon anims if I shot it. if( EV_IsLocal( idx ) ) - gEngfuncs.pEventAPI->EV_WeaponAnimation ( g_fireAnims1[gEngfuncs.pfnRandomLong( 0, 3 )], 1 ); + gEngfuncs.pEventAPI->EV_WeaponAnimation( g_fireAnims1[gEngfuncs.pfnRandomLong( 0, 3 )], 1 ); if( iStartup == 1 && EV_IsLocal( idx ) && !pBeam && !pBeam2 && cl_lw->value ) //Adrian: Added the cl_lw check for those lital people that hate weapon prediction. { From 55c3eb674c83cd511a34ea769885cbd6e43f09ad Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 17:39:50 +0500 Subject: [PATCH 037/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/35fd286ccaf7426a95baf30e682410510fe77083 --- dlls/monsters.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index 5f112a62..a9796a80 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -3357,6 +3357,9 @@ CBaseEntity *CBaseMonster::DropItem( const char *pszItemName, const Vector &vecP // do we want this behavior to be default?! (sjb) pItem->pev->velocity = pev->velocity; pItem->pev->avelocity = Vector( 0, RANDOM_FLOAT( 0, 100 ), 0 ); + + // Dropped items should never respawn (unless this rule changes in the future). - Solokiller + pItem->pev->spawnflags |= SF_NORESPAWN; return pItem; } else From 33ba064b88d9b0e818009049aef13f53bd16ae20 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 17:53:04 +0500 Subject: [PATCH 038/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/4dfa6b8710a0a30761b298a02bee21c65f056327 --- cl_dll/ev_hldm.cpp | 2 -- dlls/crowbar.cpp | 9 ++++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 381c9179..7d2464e8 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -1159,8 +1159,6 @@ void EV_Crowbar( event_args_t *args ) if( EV_IsLocal( idx ) ) { - gEngfuncs.pEventAPI->EV_WeaponAnimation( CROWBAR_ATTACK1MISS, 1 ); - switch( (g_iSwing++) % 3 ) { case 0: diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index 65e21162..98808e14 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -183,9 +183,12 @@ int CCrowbar::Swing( int fFirst ) } } #endif - PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usCrowbar, - 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, - 0, 0, 0 ); + if( fFirst ) + { + PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usCrowbar, + 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, + 0, 0, 0 ); + } if( tr.flFraction >= 1.0 ) { From 033bbbcd80bce28b4a5b25f5362e28d43b909474 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 18:04:09 +0500 Subject: [PATCH 039/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/3680342c619bf2efef9a8e2e99c72f4469a89bbd --- cl_dll/ammo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index 3d214280..f439520e 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -536,7 +536,7 @@ int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) if( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) { - static wrect_t nullrc; + wrect_t nullrc = {}; gpActiveSel = NULL; SetCrosshair( 0, nullrc, 0, 0, 0 ); } @@ -556,7 +556,7 @@ int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) // int CHudAmmo::MsgFunc_CurWeapon( const char *pszName, int iSize, void *pbuf ) { - static wrect_t nullrc; + wrect_t nullrc = {}; int fOnTarget = FALSE; BEGIN_READ( pbuf, iSize ); From 6f44185a645266d2fb7ea8bc5136b6b57f650a61 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 18:31:35 +0500 Subject: [PATCH 040/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/0398781544bce0766545fbbb8ac8367e3db6c86b --- cl_dll/ev_hldm.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 7d2464e8..7bb3a797 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -521,16 +521,17 @@ void EV_FireGlock2( event_args_t *args ) VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); + int empty = args->bparam1; AngleVectors( angles, forward, right, up ); - shell = gEngfuncs.pEventAPI->EV_FindModelIndex ("models/shell.mdl");// brass shell + shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/shell.mdl" );// brass shell if( EV_IsLocal( idx ) ) { // Add muzzle flash to current weapon model EV_MuzzleFlash(); - gEngfuncs.pEventAPI->EV_WeaponAnimation( GLOCK_SHOOT, 2 ); + gEngfuncs.pEventAPI->EV_WeaponAnimation( empty ? GLOCK_SHOOT_EMPTY : GLOCK_SHOOT, 2 ); V_PunchAxis( 0, -2.0 ); } From e7b324da5ebd26b0eae9c080911fd40c6ca478fb Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 19:17:59 +0500 Subject: [PATCH 041/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/19c8e45d8f92d0e09171f9f1b5b3fd0f25d109b6 --- dlls/mp5.cpp | 6 ++++++ dlls/weapons.h | 1 + 2 files changed, 7 insertions(+) diff --git a/dlls/mp5.cpp b/dlls/mp5.cpp index 7131f888..a13257a1 100644 --- a/dlls/mp5.cpp +++ b/dlls/mp5.cpp @@ -270,6 +270,12 @@ void CMP5::WeaponIdle( void ) m_flTimeWeaponIdle = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); // how long till we do this again. } +BOOL CMP5::IsUseable() +{ + //Can be used if the player has AR grenades. - Solokiller + return CBasePlayerWeapon::IsUseable() || m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] > 0; +} + class CMP5AmmoClip : public CBasePlayerAmmo { void Spawn( void ) diff --git a/dlls/weapons.h b/dlls/weapons.h index 7d99e8a6..86e9c7f6 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -563,6 +563,7 @@ public: BOOL Deploy( void ); void Reload( void ); void WeaponIdle( void ); + BOOL IsUseable(); float m_flNextAnimTime; int m_iShell; From 19bdc1d01b7287cd61b58fb7b7bdb6953caa50a8 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 19:48:01 +0500 Subject: [PATCH 042/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/33413807d0ca23f3d9121e45f5584cb5be98751b --- dlls/gauss.cpp | 36 ++++++++++++++++++++++++++---------- dlls/weapons.h | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index 93352b57..0ebb876c 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -123,6 +123,12 @@ int CGauss::GetItemInfo( ItemInfo *p ) return 1; } +BOOL CGauss::IsUseable() +{ + // Currently charging, allow the player to fire it first. - Solokiller + return CBasePlayerWeapon::IsUseable() || m_InAttack != 0; +} + BOOL CGauss::Deploy() { m_pPlayer->m_flPlayAftershock = 0.0; @@ -224,6 +230,22 @@ void CGauss::SecondaryAttack() } else { + // Moved to before the ammo burn. + // Because we drained 1 when m_InAttack == 0, then 1 again now before checking if we're out of ammo, + // this resuled in the player having -1 ammo, which in turn caused CanDeploy to think it could be deployed. + // This will need to be fixed further down the line by preventing negative ammo unless explicitly required (infinite ammo?), + // But this check will prevent the problem for now. - Solokiller + // TODO: investigate further. + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) + { + // out of ammo! force the gun to fire + StartFire(); + m_fInAttack = 0; + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0; + m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1; + return; + } + // during the charging process, eat one bit of ammo every once in a while if( UTIL_WeaponTimeBase() >= m_pPlayer->m_flNextAmmoBurn && m_pPlayer->m_flNextAmmoBurn != 1000 ) { @@ -243,16 +265,6 @@ void CGauss::SecondaryAttack() } } - if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) - { - // out of ammo! force the gun to fire - StartFire(); - m_fInAttack = 0; - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0; - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1; - return; - } - if( UTIL_WeaponTimeBase() >= m_pPlayer->m_flAmmoStartCharge ) { // don't eat any more ammo after gun is fully charged. @@ -558,6 +570,10 @@ void CGauss::WeaponIdle( void ) StartFire(); m_fInAttack = 0; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0; + + // Need to set m_flNextPrimaryAttack so the weapon gets a chance to complete its secondary fire animation. - Solokiller + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) + m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.5; } else { diff --git a/dlls/weapons.h b/dlls/weapons.h index 86e9c7f6..736dadd4 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -741,7 +741,7 @@ public: int iItemSlot( void ) { return 4; } int GetItemInfo(ItemInfo *p); int AddToPlayer( CBasePlayer *pPlayer ); - + BOOL IsUseable(); BOOL Deploy( void ); void Holster( int skiplocal = 0 ); From 9ef79aee9ef6924dfdfe2ec1538dc0d26fe8a0f8 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 21:44:06 +0500 Subject: [PATCH 043/211] Merge https://github.com/ValveSoftware/halflife/pull/1720/commits/6f020090bd75706174012bb080fce8f4b6a2d187 --- dlls/rpg.cpp | 8 ++++---- dlls/weapons.cpp | 2 +- dlls/weapons.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index 021ad534..5fb8cc70 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -109,8 +109,8 @@ CRpgRocket *CRpgRocket::CreateRpgRocket( Vector vecOrigin, Vector vecAngles, CBa pRocket->pev->angles = vecAngles; pRocket->Spawn(); pRocket->SetTouch( &CRpgRocket::RocketTouch ); - pRocket->m_pLauncher = pLauncher;// remember what RPG fired me. - pRocket->m_pLauncher->m_cActiveRockets++;// register this missile as active for the launcher + pRocket->m_hLauncher = pLauncher;// remember what RPG fired me. + pLauncher->m_cActiveRockets++;// register this missile as active for the launcher pRocket->pev->owner = pOwner->edict(); return pRocket; @@ -150,10 +150,10 @@ void CRpgRocket::Spawn( void ) //========================================================= void CRpgRocket::RocketTouch( CBaseEntity *pOther ) { - if( m_pLauncher ) + if( CRpg* pLauncher = (CRpg*)( (CBaseEntity*)( m_hLauncher ) ) ) { // my launcher is still around, tell it I'm dead. - m_pLauncher->m_cActiveRockets--; + pLauncher->m_cActiveRockets--; } STOP_SOUND( edict(), CHAN_VOICE, "weapons/rocket1.wav" ); diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index ff083ee7..bc508c6a 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -1518,7 +1518,7 @@ IMPLEMENT_SAVERESTORE( CRpg, CBasePlayerWeapon ) TYPEDESCRIPTION CRpgRocket::m_SaveData[] = { DEFINE_FIELD( CRpgRocket, m_flIgniteTime, FIELD_TIME ), - DEFINE_FIELD( CRpgRocket, m_pLauncher, FIELD_CLASSPTR ), + DEFINE_FIELD( CRpgRocket, m_hLauncher, FIELD_EHANDLE ), }; IMPLEMENT_SAVERESTORE( CRpgRocket, CGrenade ) diff --git a/dlls/weapons.h b/dlls/weapons.h index 736dadd4..3d8dd6ad 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -725,7 +725,7 @@ public: int m_iTrail; float m_flIgniteTime; - CRpg *m_pLauncher;// pointer back to the launcher that fired me. + EHANDLE m_hLauncher; // handle back to the launcher that fired me. }; class CGauss : public CBasePlayerWeapon From e98f45b2796670989b9ac219cbe99f4df9845e51 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 21:53:57 +0500 Subject: [PATCH 044/211] Merge https://github.com/ValveSoftware/halflife/pull/1599 --- dlls/weapons.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index bc508c6a..61b038c0 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -578,6 +578,13 @@ void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) } SUB_UseTargets( pOther, USE_TOGGLE, 0 ); // UNDONE: when should this happen? + + // If the item is falling and its Think remains FallItem after the player picks it up, + // then after the item touches the ground its Touch will be set back to DefaultTouch, + // so the player will pick it up again, this time Kill-ing the item (since we already have it in the inventory), + // which will make the pointer bad and crash the game. + if( m_pfnThink == &CBasePlayerItem::FallThink ) + SetThink( NULL ); } BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted ) From cf5b2f9e14fdc87f3c58b8780834fffd9cec8fd7 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 5 Jul 2017 23:50:55 +0500 Subject: [PATCH 045/211] Merge https://github.com/ValveSoftware/halflife/pull/1601 --- cl_dll/cdll_int.cpp | 14 ++++++++++++++ dlls/client.cpp | 14 +++++++++++++- dlls/game.cpp | 2 ++ dlls/player.cpp | 13 +++++++++++++ dlls/player.h | 10 ++++++---- pm_shared/pm_shared.c | 13 ++++++++----- 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index ffd342d2..d71659e9 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -21,6 +21,7 @@ #include "hud.h" #include "cl_util.h" #include "netadr.h" +#include "parsemsg.h" extern "C" { @@ -32,10 +33,21 @@ extern "C" cl_enginefunc_t gEngfuncs; CHud gHUD; mobile_engfuncs_t *gMobileEngfuncs = NULL; + +extern "C" int g_bhopcap; void InitInput( void ); void EV_HookEvents( void ); void IN_Commands( void ); +int __MsgFunc_Bhopcap( const char *pszName, int iSize, void *pbuf ) +{ + BEGIN_READ( pbuf, iSize ); + + g_bhopcap = READ_BYTE(); + + return 1; +} + /* ========================== Initialize @@ -196,6 +208,8 @@ void DLLEXPORT HUD_Init( void ) { InitInput(); gHUD.Init(); + + gEngfuncs.pfnHookUserMsg( "Bhopcap", __MsgFunc_Bhopcap ); } /* diff --git a/dlls/client.cpp b/dlls/client.cpp index 7354f68f..1fead362 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -48,11 +48,15 @@ extern DLL_GLOBAL ULONG g_ulFrameCount; extern void CopyToBodyQue( entvars_t* pev ); extern int giPrecacheGrunt; extern int gmsgSayText; +extern int gmsgBhopcap; extern cvar_t allow_spectators; extern int g_teamplay; +extern cvar_t bhopcap; +extern "C" int g_bhopcap; + void LinkUserMessages( void ); /* @@ -799,8 +803,16 @@ void StartFrame( void ) gpGlobals->teamplay = teamplay.value; g_ulFrameCount++; -} + int oldBhopcap = g_bhopcap; + g_bhopcap = ( g_pGameRules->IsMultiplayer() && bhopcap.value != 0.0f ) ? 1 : 0; + if( g_bhopcap != oldBhopcap ) + { + MESSAGE_BEGIN( MSG_ALL, gmsgBhopcap, NULL ); + WRITE_BYTE( g_bhopcap ); + MESSAGE_END(); + } +} void ClientPrecache( void ) { diff --git a/dlls/game.cpp b/dlls/game.cpp index fb247903..7905075a 100644 --- a/dlls/game.cpp +++ b/dlls/game.cpp @@ -38,6 +38,7 @@ cvar_t teamlist = { "mp_teamlist","hgrunt;scientist", FCVAR_SERVER }; cvar_t teamoverride = { "mp_teamoverride","1" }; cvar_t defaultteam = { "mp_defaultteam","0" }; cvar_t allowmonsters = { "mp_allowmonsters","0", FCVAR_SERVER }; +cvar_t bhopcap = { "mp_bhopcap", "1", FCVAR_SERVER }; cvar_t allow_spectators = { "allow_spectators", "0", FCVAR_SERVER }; // 0 prevents players from being spectators @@ -473,6 +474,7 @@ void GameDLLInit( void ) CVAR_REGISTER( &teamoverride ); CVAR_REGISTER( &defaultteam ); CVAR_REGISTER( &allowmonsters ); + CVAR_REGISTER( &bhopcap ); CVAR_REGISTER( &mp_chattime ); diff --git a/dlls/player.cpp b/dlls/player.cpp index 51995acf..b838f35f 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -45,6 +45,8 @@ extern DLL_GLOBAL BOOL g_fDrawLines; int gEvilImpulse101; extern DLL_GLOBAL int g_iSkillLevel, gDisplayTitle; +extern "C" int g_bhopcap; + BOOL gInitHUD = TRUE; extern void CopyToBodyQue( entvars_t *pev); @@ -181,6 +183,7 @@ int gmsgSetFOV = 0; int gmsgShowMenu = 0; int gmsgGeigerRange = 0; int gmsgTeamNames = 0; +int gmsgBhopcap = 0; int gmsgStatusText = 0; int gmsgStatusValue = 0; @@ -227,6 +230,7 @@ void LinkUserMessages( void ) gmsgFade = REG_USER_MSG( "ScreenFade", sizeof(ScreenFade) ); gmsgAmmoX = REG_USER_MSG( "AmmoX", 2 ); gmsgTeamNames = REG_USER_MSG( "TeamNames", -1 ); + gmsgBhopcap = REG_USER_MSG( "Bhopcap", 1 ); gmsgStatusText = REG_USER_MSG( "StatusText", -1 ); gmsgStatusValue = REG_USER_MSG( "StatusValue", 3 ); @@ -4072,6 +4076,15 @@ void CBasePlayer::UpdateClientData( void ) UpdateStatusBar(); m_flNextSBarUpdateTime = gpGlobals->time + 0.2; } + + // Send the current bhopcap state. + if( !m_bSentBhopcap ) + { + m_bSentBhopcap = true; + MESSAGE_BEGIN( MSG_ONE, gmsgBhopcap, NULL, pev ); + WRITE_BYTE( g_bhopcap ); + MESSAGE_END(); + } } //========================================================= diff --git a/dlls/player.h b/dlls/player.h index b2dce868..8ff312ea 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -313,13 +313,15 @@ public: //Player ID void InitStatusBar( void ); void UpdateStatusBar( void ); - int m_izSBarState[ SBAR_END ]; + int m_izSBarState[SBAR_END]; float m_flNextSBarUpdateTime; float m_flStatusBarDisappearDelay; - char m_SbarString0[ SBAR_STRING_SIZE ]; - char m_SbarString1[ SBAR_STRING_SIZE ]; + char m_SbarString0[SBAR_STRING_SIZE]; + char m_SbarString1[SBAR_STRING_SIZE]; float m_flNextChatTime; + + bool m_bSentBhopcap; // If false, the player just joined and needs a bhopcap message. }; #define AUTOAIM_2DEGREES 0.0348994967025 @@ -327,7 +329,7 @@ public: #define AUTOAIM_8DEGREES 0.1391731009601 #define AUTOAIM_10DEGREES 0.1736481776669 -extern int gmsgHudText; +extern int gmsgHudText; extern BOOL gInitHUD; #endif // PLAYER_H diff --git a/pm_shared/pm_shared.c b/pm_shared/pm_shared.c index c709ba14..9aed8093 100644 --- a/pm_shared/pm_shared.c +++ b/pm_shared/pm_shared.c @@ -27,11 +27,13 @@ #include // atoi #include // isspace +int g_bhopcap = 1; + #ifdef CLIENT_DLL - // Spectator Mode - int iJumpSpectator; -extern float vJumpOrigin[3]; -extern float vJumpAngles[3]; +// Spectator Mode +int iJumpSpectator; +extern float vJumpOrigin[3]; +extern float vJumpAngles[3]; #endif static int pm_shared_initialized = 0; @@ -2556,7 +2558,8 @@ void PM_Jump( void ) // In the air now. pmove->onground = -1; - PM_PreventMegaBunnyJumping(); + if( g_bhopcap ) + PM_PreventMegaBunnyJumping(); if( tfc ) { From 85edea072b35d0dce99f60ad5fb11a1cd82e3e67 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 6 Jul 2017 00:10:06 +0500 Subject: [PATCH 046/211] Merge https://github.com/ValveSoftware/halflife/pull/1590/commits/136de25b61689ee30ca0206e6737c7d06be77567 --- cl_dll/menu.cpp | 10 ++++++---- cl_dll/text_message.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cl_dll/menu.cpp b/cl_dll/menu.cpp index 5f710a33..fc24b917 100644 --- a/cl_dll/menu.cpp +++ b/cl_dll/menu.cpp @@ -83,7 +83,7 @@ int CHudMenu::Draw( float flTime ) int nlc = 0; for( i = 0; i < MAX_MENU_STRING && g_szMenuString[i] != '\0'; i++ ) { - if ( g_szMenuString[i] == '\n' ) + if( g_szMenuString[i] == '\n' ) nlc++; } @@ -153,19 +153,21 @@ int CHudMenu::MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf ) else { // append to the current menu string - strncat( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING - strlen( g_szPrelocalisedMenuString ) ); + strncat( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING - strlen( g_szPrelocalisedMenuString ) - 1 ); } g_szPrelocalisedMenuString[MAX_MENU_STRING - 1] = 0; // ensure null termination (strncat/strncpy does not) if( !NeedMore ) { // we have the whole string, so we can localise it now - strcpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString ) ); + strncpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString ), MAX_MENU_STRING ); + g_szMenuString[MAX_MENU_STRING - 1] = '\0'; // Swap in characters if( KB_ConvertString( g_szMenuString, &temp ) ) { - strcpy( g_szMenuString, temp ); + strncpy( g_szMenuString, temp, MAX_MENU_STRING ); + g_szMenuString[MAX_MENU_STRING - 1] = '\0'; free( temp ); } } diff --git a/cl_dll/text_message.cpp b/cl_dll/text_message.cpp index 58dae6f7..9452cebb 100644 --- a/cl_dll/text_message.cpp +++ b/cl_dll/text_message.cpp @@ -45,14 +45,15 @@ int CHudTextMessage::Init( void ) char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size ) { char *dst = dst_buffer; - for( char *src = (char*)msg; *src != 0 && buffer_size > 0; buffer_size-- ) + for( char *src = (char*)msg; *src != 0 && ( buffer_size - 1 ) > 0; buffer_size-- ) { if( *src == '#' ) { // cut msg name out of string static char word_buf[255]; char *wdst = word_buf, *word_start = src; - for( ++src; ( *src >= 'A' && *src <= 'z' ) || ( *src >= '0' && *src <= '9' ); wdst++, src++ ) + int wordbuf_size = (int)sizeof(word_buf); + for( ++src; ( ( *src >= 'A' && *src <= 'z' ) || ( *src >= '0' && *src <= '9' ) ) && ( wordbuf_size - 1 ) > 0; wdst++, src++, wordbuf_size-- ) { *wdst = *src; } @@ -69,21 +70,20 @@ char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, in } // copy string into message over the msg name - for( char *wsrc = (char*)clmsg->pMessage; *wsrc != 0; wsrc++, dst++ ) + for( char *wsrc = (char*)clmsg->pMessage; *wsrc != 0 && ( buffer_size - 1 ) > 0; wsrc++, dst++, buffer_size-- ) { *dst = *wsrc; } - *dst = 0; + buffer_size++; } else { *dst = *src; dst++, src++; - *dst = 0; } } - dst_buffer[buffer_size - 1] = 0; // ensure null termination + *dst = 0; // ensure null termination return dst_buffer; } From 495c7717242f0315fced701c57dee242b48f66af Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 6 Jul 2017 00:20:29 +0500 Subject: [PATCH 047/211] Update mp5.cpp. --- dlls/mp5.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/mp5.cpp b/dlls/mp5.cpp index a13257a1..403efa04 100644 --- a/dlls/mp5.cpp +++ b/dlls/mp5.cpp @@ -238,7 +238,7 @@ void CMP5::SecondaryAttack( void ) void CMP5::Reload( void ) { - if( m_pPlayer->ammo_9mm <= 0 ) + if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == MP5_MAX_CLIP ) return; DefaultReload( MP5_MAX_CLIP, MP5_RELOAD, 1.5 ); From b66f1cb39400e586d7a2ef8eca44c2f14c226e69 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 6 Jul 2017 00:25:22 +0500 Subject: [PATCH 048/211] Update glock.cpp. --- dlls/glock.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/glock.cpp b/dlls/glock.cpp index 4e679750..3eb08d6c 100644 --- a/dlls/glock.cpp +++ b/dlls/glock.cpp @@ -109,7 +109,7 @@ void CGlock::GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim ) if( m_fFireOnEmpty ) { PlayEmptySound(); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.2; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.2 ); } return; @@ -158,7 +158,7 @@ void CGlock::GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim ) PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), fUseAutoAim ? m_usFireGlock1 : m_usFireGlock2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, ( m_iClip == 0 ) ? 1 : 0, 0 ); - m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + flCycleTime; + m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay( flCycleTime ); if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) // HEV suit - indicate out of ammo condition From 6e1059026faa90c5bfe5e3b3f4f58fde398d4524 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 6 Jul 2017 00:41:13 +0500 Subject: [PATCH 049/211] Do not detonate hand grenade after weapon switch. --- dlls/handgrenade.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dlls/handgrenade.cpp b/dlls/handgrenade.cpp index 96119b6b..2a31fc84 100644 --- a/dlls/handgrenade.cpp +++ b/dlls/handgrenade.cpp @@ -103,6 +103,12 @@ void CHandGrenade::Holster( int skiplocal /* = 0 */ ) pev->nextthink = gpGlobals->time + 0.1; } + if( m_flStartThrow ) + { + m_flStartThrow = 0; + m_flReleaseThrow = 0; + } + EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "common/null.wav", 1.0, ATTN_NORM ); } From b7d1bd3235790026cf0d3e66053ba155f2b0a07a Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 6 Jul 2017 00:44:14 +0500 Subject: [PATCH 050/211] Merge fix for blocked door sound from bubblemod. --- dlls/doors.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dlls/doors.cpp b/dlls/doors.cpp index dcb04e00..231a3753 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -750,6 +750,11 @@ void CBaseDoor::Blocked( CBaseEntity *pOther ) // so let it just squash the object to death real fast if( m_flWait >= 0 ) { + // BMod Start - Door sound fix. + if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) + STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ) ); + // BMod End + if( m_toggle_state == TS_GOING_DOWN ) { DoorGoUp(); From bdd3e74ebd3fbf7f7d4d20cdf2e85c8f981309a3 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 6 Jul 2017 02:30:10 +0500 Subject: [PATCH 051/211] Detonate satchels under blocked door. --- dlls/doors.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dlls/doors.cpp b/dlls/doors.cpp index 231a3753..3a8613ab 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -22,6 +22,7 @@ #include "util.h" #include "cbase.h" #include "doors.h" +#include "weapons.h" extern void SetMovedir( entvars_t *ev ); @@ -746,6 +747,10 @@ void CBaseDoor::Blocked( CBaseEntity *pOther ) if( pev->dmg ) pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH ); + // Detonate satchels + if( !strcmp( "monster_satchel", STRING( pOther->pev->classname ) ) ) + ( (CSatchel*)pOther )->Use( this, this, USE_ON, 0 ); + // if a door has a negative wait, it would never come back if blocked, // so let it just squash the object to death real fast if( m_flWait >= 0 ) From c6b353e09287048fb42cd4811b5854ded5ce93bc Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 6 Jul 2017 02:35:32 +0500 Subject: [PATCH 052/211] Fix build. --- dlls/gauss.cpp | 2 +- dlls/nihilanth.cpp | 2 +- dlls/subs.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index 0ebb876c..d3e005c2 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -126,7 +126,7 @@ int CGauss::GetItemInfo( ItemInfo *p ) BOOL CGauss::IsUseable() { // Currently charging, allow the player to fire it first. - Solokiller - return CBasePlayerWeapon::IsUseable() || m_InAttack != 0; + return CBasePlayerWeapon::IsUseable() || m_fInAttack != 0; } BOOL CGauss::Deploy() diff --git a/dlls/nihilanth.cpp b/dlls/nihilanth.cpp index 82b31e13..1f9b0f88 100644 --- a/dlls/nihilanth.cpp +++ b/dlls/nihilanth.cpp @@ -356,7 +356,7 @@ void CNihilanth::UpdateOnRemove() m_pBall = 0; } - for( int i = 0; i < N_SPHERES, i++ ) + for( int i = 0; i < N_SPHERES; i++ ) { if( CBaseEntity* pSphere = (CBaseEntity *)m_hSphere[i] ) { diff --git a/dlls/subs.cpp b/dlls/subs.cpp index 4654363a..2a299ce4 100644 --- a/dlls/subs.cpp +++ b/dlls/subs.cpp @@ -112,7 +112,7 @@ void CBaseEntity::UpdateOnRemove( void ) //Killtarget didn't do this before, so the counter broke. - Solokiller if( CBaseEntity* pOwner = pev->owner ? Instance( pev->owner ) : 0 ) { - pOwner->DeathNotice( this ); + pOwner->DeathNotice( pev ); } } From f575e78a9b7320db15025e94c1d1bb2cd1922a60 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 6 Jul 2017 03:47:59 +0500 Subject: [PATCH 053/211] Register allow_spectators cvar. --- dlls/game.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/game.cpp b/dlls/game.cpp index 7905075a..9b69cac9 100644 --- a/dlls/game.cpp +++ b/dlls/game.cpp @@ -455,6 +455,7 @@ void GameDLLInit( void ) g_footsteps = CVAR_GET_POINTER( "mp_footsteps" ); CVAR_REGISTER( &displaysoundlist ); + CVAR_REGISTER( &allow_spectators ); CVAR_REGISTER( &teamplay ); CVAR_REGISTER( &fraglimit ); From 4d1dc131b924dedbb03bf40eb4bb64bd1c624f1a Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sat, 8 Jul 2017 20:06:00 +0500 Subject: [PATCH 054/211] Fix mistakes with saverestore after merge. --- dlls/util.cpp | 2 +- engine/eiface.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/util.cpp b/dlls/util.cpp index d79c9f5a..f4b09cb1 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1890,7 +1890,7 @@ void CSave::WriteFunction( const char *pname, void **data, int count ) { const char *functionName; - functionName = NAME_FOR_FUNCTION( (unsigned int)(size_t)*data ); + functionName = NAME_FOR_FUNCTION( (size_t)*data ); if( functionName ) BufferField( pname, strlen( functionName ) + 1, functionName ); else diff --git a/engine/eiface.h b/engine/eiface.h index 30f8a82a..23cb17f8 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -172,8 +172,8 @@ typedef struct enginefuncs_s int (*pfnRegUserMsg)( const char *pszName, int iSize ); void (*pfnAnimationAutomove)( const edict_t* pEdict, float flTime ); void (*pfnGetBonePosition)( const edict_t* pEdict, int iBone, float *rgflOrigin, float *rgflAngles ); - unsigned int (*pfnFunctionFromName)( const char *pName ); - const char *(*pfnNameForFunction)( unsigned int function ); + size_t (*pfnFunctionFromName)( const char *pName ); + const char *(*pfnNameForFunction)( size_t function ); void (*pfnClientPrintf)( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg ); // JOHN: engine callbacks so game DLL can print messages to individual clients void (*pfnServerPrint)( const char *szMsg ); const char *(*pfnCmd_Args)( void ); // these 3 added From c16e1ecfef45f5a6b67ff470051c328cc7e760b6 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sat, 8 Jul 2017 20:13:41 +0500 Subject: [PATCH 055/211] A little fix for nodes on 64bit arches. --- dlls/nodes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dlls/nodes.h b/dlls/nodes.h index 2b582a6f..f5ebcd84 100644 --- a/dlls/nodes.h +++ b/dlls/nodes.h @@ -104,7 +104,11 @@ typedef struct //========================================================= // CGraph //========================================================= +#if defined(__amd64__) || defined(__aarch64__) +#define GRAPH_VERSION (int)17// Was incremented for 64bit arches, because .nod-files have incombatibilities on different arches. +#else #define GRAPH_VERSION (int)16// !!!increment this whever graph/node/link classes change, to obsolesce older disk files. +#endif class CGraph { From 3bce17e3a04f8af10a927a07ceb8ab0f09152ec4 Mon Sep 17 00:00:00 2001 From: mittorn Date: Sat, 8 Jul 2017 20:26:21 +0000 Subject: [PATCH 056/211] Fix saverestore on LP64 --- dlls/saverestore.h | 2 +- dlls/util.cpp | 6 +++--- engine/eiface.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dlls/saverestore.h b/dlls/saverestore.h index f76613e8..a9ad2c54 100644 --- a/dlls/saverestore.h +++ b/dlls/saverestore.h @@ -59,7 +59,7 @@ public: void WriteVector( const char *pname, const float *value, int count ); // Save a vector void WritePositionVector( const char *pname, const Vector &value ); // Offset for landmark if necessary void WritePositionVector( const char *pname, const float *value, int count ); // array of pos vectors - void WriteFunction( const char *pname, const int *value, int count ); // Save a function pointer + void WriteFunction( const char *pname, void **value, int count ); // Save a function pointer int WriteEntVars( const char *pname, entvars_t *pev ); // Save entvars_t (entvars_t) int WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); diff --git a/dlls/util.cpp b/dlls/util.cpp index d1fceb0a..1c229edd 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1886,7 +1886,7 @@ void CSave::WritePositionVector( const char *pname, const float *value, int coun } } -void CSave::WriteFunction( const char *pname, const int *data, int count ) +void CSave::WriteFunction( const char *pname, void **data, int count ) { const char *functionName; @@ -1894,7 +1894,7 @@ void CSave::WriteFunction( const char *pname, const int *data, int count ) if( functionName ) BufferField( pname, strlen( functionName ) + 1, functionName ); else - ALERT( at_error, "Invalid function pointer in entity!" ); + ALERT( at_error, "Invalid function pointer in entity!\n" ); } void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ) @@ -2042,7 +2042,7 @@ int CSave::WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFi WriteInt( pTest->fieldName, (int *)(char *)pOutputData, pTest->fieldSize ); break; case FIELD_FUNCTION: - WriteFunction( pTest->fieldName, (int *)pOutputData, pTest->fieldSize ); + WriteFunction( pTest->fieldName, (void **)pOutputData, pTest->fieldSize ); break; default: ALERT( at_error, "Bad field type\n" ); diff --git a/engine/eiface.h b/engine/eiface.h index 903451f5..b3b9d415 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -171,8 +171,8 @@ typedef struct enginefuncs_s int (*pfnRegUserMsg)( const char *pszName, int iSize ); void (*pfnAnimationAutomove)( const edict_t* pEdict, float flTime ); void (*pfnGetBonePosition)( const edict_t* pEdict, int iBone, float *rgflOrigin, float *rgflAngles ); - unsigned long (*pfnFunctionFromName)( const char *pName ); - const char *(*pfnNameForFunction)( unsigned long function ); + void* (*pfnFunctionFromName)( const char *pName ); + const char *(*pfnNameForFunction)( void *function ); void (*pfnClientPrintf)( edict_t* pEdict, PRINT_TYPE ptype, const char *szMsg ); // JOHN: engine callbacks so game DLL can print messages to individual clients void (*pfnServerPrint)( const char *szMsg ); const char *(*pfnCmd_Args)( void ); // these 3 added From 9ebfc981773ec4c7a89ffe52d9c249e1fbef9634 Mon Sep 17 00:00:00 2001 From: mittorn Date: Sat, 8 Jul 2017 21:28:31 +0000 Subject: [PATCH 057/211] Fix field sizes --- dlls/util.cpp | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/dlls/util.cpp b/dlls/util.cpp index 1c229edd..0298487b 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1584,6 +1584,33 @@ void UTIL_StripToken( const char *pKey, char *pDest ) // // -------------------------------------------------------------- static int gSizes[FIELD_TYPECOUNT] = +{ + sizeof(float), // FIELD_FLOAT + sizeof(int), // FIELD_STRING + sizeof(void*), // FIELD_ENTITY + sizeof(void*), // FIELD_CLASSPTR + sizeof(void*), // FIELD_EHANDLE + sizeof(void*), // FIELD_entvars_t + sizeof(void*), // FIELD_EDICT + sizeof(float) * 3, // FIELD_VECTOR + sizeof(float) * 3, // FIELD_POSITION_VECTOR + sizeof(void *), // FIELD_POINTER + sizeof(int), // FIELD_INTEGER +#ifdef GNUC + sizeof(void *) * 2, // FIELD_FUNCTION +#else + sizeof(void *), // FIELD_FUNCTION +#endif + sizeof(int), // FIELD_BOOLEAN + sizeof(short), // FIELD_SHORT + sizeof(char), // FIELD_CHARACTER + sizeof(float), // FIELD_TIME + sizeof(int), // FIELD_MODELNAME + sizeof(int), // FIELD_SOUNDNAME +}; + +// entities has different store size +static int gInputSizes[FIELD_TYPECOUNT] = { sizeof(float), // FIELD_FLOAT sizeof(int), // FIELD_STRING @@ -1594,12 +1621,12 @@ static int gSizes[FIELD_TYPECOUNT] = sizeof(int), // FIELD_EDICT sizeof(float) * 3, // FIELD_VECTOR sizeof(float) * 3, // FIELD_POSITION_VECTOR - sizeof(int *), // FIELD_POINTER + sizeof(void *), // FIELD_POINTER sizeof(int), // FIELD_INTEGER #ifdef GNUC - sizeof(int *) * 2, // FIELD_FUNCTION + sizeof(void *) * 2, // FIELD_FUNCTION #else - sizeof(int *), // FIELD_FUNCTION + sizeof(void *), // FIELD_FUNCTION #endif sizeof(int), // FIELD_BOOLEAN sizeof(short), // FIELD_SHORT @@ -2137,7 +2164,7 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou for( j = 0; j < pTest->fieldSize; j++ ) { void *pOutputData = ( (char *)pBaseData + pTest->fieldOffset + ( j * gSizes[pTest->fieldType] ) ); - void *pInputData = (char *)pData + j * gSizes[pTest->fieldType]; + void *pInputData = (char *)pData + j * gInputSizes[pTest->fieldType]; switch( pTest->fieldType ) { From 4d7d6f2c378f0b79fe9dd4eeb931cdb6daadd48f Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 10 Jul 2017 19:28:56 +0500 Subject: [PATCH 058/211] Turn off flashlight when player dead. --- dlls/player.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/player.cpp b/dlls/player.cpp index b838f35f..5029ce97 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -820,6 +820,9 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit ) else pev->weapons &= ~WEAPON_ALLWEAPONS; + // Turn off flashlight + ClearBits( pev->effects, EF_DIMLIGHT ); + for( i = 0; i < MAX_AMMO_SLOTS; i++ ) m_rgAmmo[i] = 0; From 2324270cc27d818923391f6d34319fb4cd258795 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 10 Jul 2017 22:18:45 +0500 Subject: [PATCH 059/211] Do not reduce armor value when godmode is active. --- dlls/player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/player.cpp b/dlls/player.cpp index 5029ce97..852abca3 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -466,7 +466,7 @@ int CBasePlayer::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, fl m_lastDamageAmount = (int)flDamage; // Armor. - if( pev->armorvalue && !( bitsDamageType & ( DMG_FALL | DMG_DROWN ) ) )// armor doesn't protect against fall or drown damage! + if( !( pev->flags & FL_GODMODE ) && pev->armorvalue && !( bitsDamageType & ( DMG_FALL | DMG_DROWN ) ) )// armor doesn't protect against fall or drown damage! { float flNew = flDamage * flRatio; From 77d077c83dc3384ee6c6134a04657ea1259847f3 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 11 Jul 2017 01:32:53 +0500 Subject: [PATCH 060/211] Partially merge https://github.com/SamVanheer/HLEnhanced/commit/3563a1846fc8905bb7357c103212a6e10b5f048b --- dlls/plats.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/dlls/plats.cpp b/dlls/plats.cpp index 203f5d9b..a60e6706 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -248,7 +248,7 @@ public: virtual int ObjectCaps( void ) { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; } void SpawnInsideTrigger( CFuncPlat *pPlatform ); void Touch( CBaseEntity *pOther ); - CFuncPlat *m_pPlatform; + EHANDLE m_pPlatform; }; /*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER @@ -340,24 +340,24 @@ static void PlatSpawnInsideTrigger( entvars_t *pevPlatform ) // void CPlatTrigger::SpawnInsideTrigger( CFuncPlat *pPlatform ) { - m_pPlatform = pPlatform; + m_hPlatform = pPlatform; // Create trigger entity, "point" it at the owning platform, give it a touch method pev->solid = SOLID_TRIGGER; pev->movetype = MOVETYPE_NONE; pev->origin = pPlatform->pev->origin; // Establish the trigger field's size - Vector vecTMin = m_pPlatform->pev->mins + Vector( 25, 25, 0 ); - Vector vecTMax = m_pPlatform->pev->maxs + Vector( 25, 25, 8 ); - vecTMin.z = vecTMax.z - ( m_pPlatform->m_vecPosition1.z - m_pPlatform->m_vecPosition2.z + 8 ); - if( m_pPlatform->pev->size.x <= 50 ) + Vector vecTMin = pPlatform->pev->mins + Vector( 25, 25, 0 ); + Vector vecTMax = pPlatform->pev->maxs + Vector( 25, 25, 8 ); + vecTMin.z = vecTMax.z - ( pPlatform->m_vecPosition1.z - pPlatform->m_vecPosition2.z + 8 ); + if( pPlatform->pev->size.x <= 50 ) { - vecTMin.x = ( m_pPlatform->pev->mins.x + m_pPlatform->pev->maxs.x ) / 2; + vecTMin.x = ( pPlatform->pev->mins.x + pPlatform->pev->maxs.x ) / 2; vecTMax.x = vecTMin.x + 1; } - if( m_pPlatform->pev->size.y <= 50 ) + if( pPlatform->pev->size.y <= 50 ) { - vecTMin.y = ( m_pPlatform->pev->mins.y + m_pPlatform->pev->maxs.y ) / 2; + vecTMin.y = ( pPlatform->pev->mins.y + pPlatform->pev->maxs.y ) / 2; vecTMax.y = vecTMin.y + 1; } UTIL_SetSize( pev, vecTMin, vecTMax ); @@ -373,15 +373,17 @@ void CPlatTrigger::Touch( CBaseEntity *pOther ) if( !FClassnameIs( pevToucher, "player" ) ) return; + CFuncPlat *pPlatform = (CFuncPlat*)(CBaseEntity*)m_hPlatform; + // Ignore touches by corpses if( !pOther->IsAlive() ) return; // Make linked platform go up/down. - if( m_pPlatform->m_toggle_state == TS_AT_BOTTOM ) - m_pPlatform->GoUp(); - else if( m_pPlatform->m_toggle_state == TS_AT_TOP ) - m_pPlatform->pev->nextthink = m_pPlatform->pev->ltime + 1;// delay going down + if( pPlatform->m_toggle_state == TS_AT_BOTTOM ) + pPlatform->GoUp(); + else if( pPlatform->m_toggle_state == TS_AT_TOP ) + pPlatform->pev->nextthink = pPlatform->pev->ltime + 1;// delay going down } // From 2df762e705d4726d5017b670138660bc8079053a Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 11 Jul 2017 01:40:26 +0500 Subject: [PATCH 061/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/f8db63a45bcc62d6110051109daca77031699df8 --- dlls/plats.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/dlls/plats.cpp b/dlls/plats.cpp index a60e6706..5d5d1f07 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -375,6 +375,13 @@ void CPlatTrigger::Touch( CBaseEntity *pOther ) CFuncPlat *pPlatform = (CFuncPlat*)(CBaseEntity*)m_hPlatform; + if( FNullEnt( pPlatform ) ) + { + // The target platform has been removed, remove myself as well. - Solokiller + UTIL_Remove( this ); + return; + } + // Ignore touches by corpses if( !pOther->IsAlive() ) return; @@ -429,7 +436,7 @@ void CFuncPlat::GoDown( void ) } // -// Platform has hit bottom. Stops and waits forever. +// Platform has hit bottom. Stops and waits forever. // void CFuncPlat::HitBottom( void ) { @@ -458,7 +465,7 @@ void CFuncPlat::GoUp( void ) } // -// Platform has hit top. Pauses, then starts back down again. +// Platform has hit top. Pauses, then starts back down again. // void CFuncPlat::HitTop( void ) { @@ -556,7 +563,7 @@ void CFuncPlatRot::GoDown( void ) } // -// Platform has hit bottom. Stops and waits forever. +// Platform has hit bottom. Stops and waits forever. // void CFuncPlatRot::HitBottom( void ) { @@ -575,7 +582,7 @@ void CFuncPlatRot::GoUp( void ) } // -// Platform has hit top. Pauses, then starts back down again. +// Platform has hit top. Pauses, then starts back down again. // void CFuncPlatRot::HitTop( void ) { @@ -857,8 +864,8 @@ void CFuncTrain::Precache( void ) case 1: PRECACHE_SOUND( "plats/train2.wav" ); PRECACHE_SOUND( "plats/train1.wav" ); - pev->noise = MAKE_STRING("plats/train2.wav" ); - pev->noise1 = MAKE_STRING("plats/train1.wav" ); + pev->noise = MAKE_STRING( "plats/train2.wav" ); + pev->noise1 = MAKE_STRING( "plats/train1.wav" ); break; case 2: PRECACHE_SOUND( "plats/platmove1.wav" ); From 8455d693609863c48108aeaff11d9b8e3f59fb49 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 11 Jul 2017 01:58:22 +0500 Subject: [PATCH 062/211] Merge https://github.com/SamVanheer/HLEnhanced/commit/d6732ca0795e1be23bea808782eb4dfd13cbd1aa --- dlls/player.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/player.cpp b/dlls/player.cpp index 852abca3..9680aaf6 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -3661,7 +3661,9 @@ int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) pev->viewmodel = 0; pev->weaponmodel = 0; } - else if( m_pLastItem == pItem ) + + // In some cases an item can be both the active and last item, like for instance dropping all weapons and only having an exhaustible weapon left. - Solokiller + if( m_pLastItem == pItem ) m_pLastItem = NULL; CBasePlayerItem *pPrev = m_rgpPlayerItems[pItem->iItemSlot()]; From 1c1d9ae18385f1a152c93f115289defbd64394ab Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 11 Jul 2017 02:24:19 +0500 Subject: [PATCH 063/211] Remove unneeded strcpy usage. --- cl_dll/com_weapons.cpp | 2 +- cl_dll/com_weapons.h | 2 +- cl_dll/ev_hldm.cpp | 19 +++++++++---------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/cl_dll/com_weapons.cpp b/cl_dll/com_weapons.cpp index 774df091..5621149b 100644 --- a/cl_dll/com_weapons.cpp +++ b/cl_dll/com_weapons.cpp @@ -283,7 +283,7 @@ unsigned short stub_PrecacheEvent( int type, const char *s ) return 0; } -const char *stub_NameForFunction( unsigned int function ) +const char *stub_NameForFunction( void *function ) { return "func"; } diff --git a/cl_dll/com_weapons.h b/cl_dll/com_weapons.h index 8559e20b..0a538f0f 100644 --- a/cl_dll/com_weapons.h +++ b/cl_dll/com_weapons.h @@ -34,7 +34,7 @@ void HUD_SetMaxSpeed( const struct edict_s *ed, float speed ); int stub_PrecacheModel( const char* s ); int stub_PrecacheSound( const char* s ); unsigned short stub_PrecacheEvent( int type, const char *s ); -const char *stub_NameForFunction( unsigned int function ); +const char *stub_NameForFunction( void *function ); void stub_SetModel( struct edict_s *e, const char *m ); extern cvar_t *cl_lw; diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 7bb3a797..d94f9fea 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -1695,7 +1695,7 @@ void EV_TrainPitchAdjust( event_args_t *args ) int pitch; int stop; - char sz[256]; + const char *pszSound; idx = args->entindex; @@ -1711,36 +1711,35 @@ void EV_TrainPitchAdjust( event_args_t *args ) switch( noise ) { case 1: - strcpy( sz, "plats/ttrain1.wav" ); + pszSound = "plats/ttrain1.wav"; break; case 2: - strcpy( sz, "plats/ttrain2.wav" ); + pszSound = "plats/ttrain2.wav"; break; case 3: - strcpy( sz, "plats/ttrain3.wav" ); + pszSound = "plats/ttrain3.wav"; break; case 4: - strcpy( sz, "plats/ttrain4.wav"); + pszSound = "plats/ttrain4.wav"; break; case 5: - strcpy( sz, "plats/ttrain6.wav"); + pszSound = "plats/ttrain6.wav"; break; case 6: - strcpy( sz, "plats/ttrain7.wav"); + pszSound = "plats/ttrain7.wav"; break; default: // no sound - strcpy( sz, "" ); return; } if( stop ) { - gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, sz ); + gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, pszSound ); } else { - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, sz, m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, pitch ); + gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, pszSound, m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, pitch ); } } From a383a57a09351365b5b3beb78d26ec0c035df4ef Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 11 Jul 2017 02:43:24 +0500 Subject: [PATCH 064/211] Fix build. --- dlls/plats.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/plats.cpp b/dlls/plats.cpp index 5d5d1f07..00b05bec 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -248,7 +248,7 @@ public: virtual int ObjectCaps( void ) { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; } void SpawnInsideTrigger( CFuncPlat *pPlatform ); void Touch( CBaseEntity *pOther ); - EHANDLE m_pPlatform; + EHANDLE m_hPlatform; }; /*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER @@ -375,7 +375,7 @@ void CPlatTrigger::Touch( CBaseEntity *pOther ) CFuncPlat *pPlatform = (CFuncPlat*)(CBaseEntity*)m_hPlatform; - if( FNullEnt( pPlatform ) ) + if( !pPlatform ) { // The target platform has been removed, remove myself as well. - Solokiller UTIL_Remove( this ); From 4661b5c1a5245b27a5532745c11e44b5540e4172 Mon Sep 17 00:00:00 2001 From: mittorn Date: Fri, 14 Jul 2017 13:11:58 +0000 Subject: [PATCH 065/211] Increase graph version --- dlls/nodes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dlls/nodes.h b/dlls/nodes.h index 27b890ed..cbf1e2a6 100644 --- a/dlls/nodes.h +++ b/dlls/nodes.h @@ -103,7 +103,11 @@ typedef struct //========================================================= // CGraph //========================================================= +#ifdef __amd64 +#define GRAPH_VERSION (int)16 * 10 +#else #define GRAPH_VERSION (int)16// !!!increment this whever graph/node/link classes change, to obsolesce older disk files. +#endif class CGraph { From a08bd614fe524d8c827ac34810a130b6f2dc90ba Mon Sep 17 00:00:00 2001 From: mittorn Date: Fri, 14 Jul 2017 13:15:17 +0000 Subject: [PATCH 066/211] Fix client build --- cl_dll/com_weapons.cpp | 2 +- cl_dll/com_weapons.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cl_dll/com_weapons.cpp b/cl_dll/com_weapons.cpp index 4f539df9..d359a3f1 100644 --- a/cl_dll/com_weapons.cpp +++ b/cl_dll/com_weapons.cpp @@ -283,7 +283,7 @@ unsigned short stub_PrecacheEvent( int type, const char *s ) return 0; } -const char *stub_NameForFunction( unsigned long function ) +const char *stub_NameForFunction( void *function ) { return "func"; } diff --git a/cl_dll/com_weapons.h b/cl_dll/com_weapons.h index 7e1fdd77..4ce861f4 100644 --- a/cl_dll/com_weapons.h +++ b/cl_dll/com_weapons.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // @@ -34,7 +34,7 @@ void HUD_SetMaxSpeed( const struct edict_s *ed, float speed ); int stub_PrecacheModel( char* s ); int stub_PrecacheSound( char* s ); unsigned short stub_PrecacheEvent( int type, const char *s ); -const char *stub_NameForFunction( unsigned long function ); +const char *stub_NameForFunction( void *function ); void stub_SetModel( struct edict_s *e, const char *m ); extern cvar_t *cl_lw; From 00833188dab87ef5746286479ba5aeb9d83b4a0c Mon Sep 17 00:00:00 2001 From: mittorn Date: Fri, 14 Jul 2017 13:42:47 +0000 Subject: [PATCH 067/211] Use real MAKE_STRING when possible --- dlls/util.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dlls/util.h b/dlls/util.h index e8aee878..5b00fe94 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -39,7 +39,14 @@ extern globalvars_t *gpGlobals; #if !defined __amd64__ || defined(CLIENT_DLL) #define MAKE_STRING(str) ((int)(size_t)str - (int)(size_t)STRING(0)) #else -#define MAKE_STRING ALLOC_STRING +static inline int MAKE_STRING(const char *szValue) +{ + long long ptrdiff = szValue - STRING(0); + if( ptrdiff > INT_MAX || ptrdiff < INT_MIN ) + return ALLOC_STRING(szValue); + else + return (int)ptrdiff; +} #endif inline edict_t *FIND_ENTITY_BY_CLASSNAME(edict_t *entStart, const char *pszName) From 1674a4b6d496b03da7efd689b739d721b83a9c8a Mon Sep 17 00:00:00 2001 From: mittorn Date: Fri, 14 Jul 2017 15:34:44 +0000 Subject: [PATCH 068/211] Use XASH_64BIT macro --- cl_dll/cl_dll.h | 4 ++++ dlls/extdll.h | 4 ++++ dlls/nodes.h | 2 +- dlls/util.h | 2 +- engine/studio.h | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/cl_dll/cl_dll.h b/cl_dll/cl_dll.h index fda4b812..24d1874b 100644 --- a/cl_dll/cl_dll.h +++ b/cl_dll/cl_dll.h @@ -41,6 +41,10 @@ typedef int ( *pfnUserMsgHook )( const char *pszName, int iSize, void *pbuf ); #include "exportdef.h" #include +#if defined(__LP64__) || defined(__LLP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + #define XASH_64BIT +#endif + extern cl_enginefunc_t gEngfuncs; #include "../engine/mobility_int.h" extern mobile_engfuncs_t *gMobileEngfuncs; diff --git a/dlls/extdll.h b/dlls/extdll.h index cbc7ebb9..dda1cec5 100644 --- a/dlls/extdll.h +++ b/dlls/extdll.h @@ -57,6 +57,10 @@ typedef int BOOL; #include "stdlib.h" #include "math.h" +#if defined(__LP64__) || defined(__LLP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + #define XASH_64BIT +#endif + // Header file containing definition of globalvars_t and entvars_t typedef unsigned int func_t; typedef unsigned int string_t; // from engine's pr_comp.h; diff --git a/dlls/nodes.h b/dlls/nodes.h index cbf1e2a6..c959dd2e 100644 --- a/dlls/nodes.h +++ b/dlls/nodes.h @@ -103,7 +103,7 @@ typedef struct //========================================================= // CGraph //========================================================= -#ifdef __amd64 +#ifdef XASH_64BIT #define GRAPH_VERSION (int)16 * 10 #else #define GRAPH_VERSION (int)16// !!!increment this whever graph/node/link classes change, to obsolesce older disk files. diff --git a/dlls/util.h b/dlls/util.h index 5b00fe94..a61240fd 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -36,7 +36,7 @@ extern globalvars_t *gpGlobals; // Use this instead of ALLOC_STRING on constant strings #define STRING(offset) (const char *)(gpGlobals->pStringBase + (int)offset) -#if !defined __amd64__ || defined(CLIENT_DLL) +#if !defined XASH_64BIT || defined(CLIENT_DLL) #define MAKE_STRING(str) ((int)(size_t)str - (int)(size_t)STRING(0)) #else static inline int MAKE_STRING(const char *szValue) diff --git a/engine/studio.h b/engine/studio.h index b5b709bb..5e5ec26c 100644 --- a/engine/studio.h +++ b/engine/studio.h @@ -215,7 +215,7 @@ typedef struct char label[32]; // textual name char name[64]; // file name cache_user_t cache; // cache index pointer -#ifndef __amd64 +#ifndef XASH_64BIT int data; // hack for group 0 #endif } mstudioseqgroup_t; From cbdf9b5d042bf695f85918ca8bee074ecec0d368 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 09:48:08 +0500 Subject: [PATCH 069/211] Fix knowledge bugs with satchels again. --- dlls/client.cpp | 6 ------ dlls/multiplay_gamerules.cpp | 6 ------ dlls/player.cpp | 1 + 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/dlls/client.cpp b/dlls/client.cpp index 1fead362..480a9506 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -127,12 +127,6 @@ void ClientDisconnect( edict_t *pEntity ) pEntity->v.solid = SOLID_NOT;// nonsolid UTIL_SetOrigin( &pEntity->v, pEntity->v.origin ); - CBasePlayer *pl = (CBasePlayer *)CBaseEntity::Instance( pEntity ); - if( pl->HasNamedPlayerItem( "weapon_satchel" ) ) - { - DeactivateSatchels( pl ); - } - g_pGameRules->ClientDisconnected( pEntity ); } diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 9da8d0b4..494ac4f6 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -675,12 +675,6 @@ void CHalfLifeMultiplay::PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, // let the killer paint another decal as soon as he'd like. PK->m_flNextDecalTime = gpGlobals->time; } -#ifndef HLDEMO_BUILD - if( pVictim->HasNamedPlayerItem( "weapon_satchel" ) ) - { - DeactivateSatchels( pVictim ); - } -#endif } //========================================================= diff --git a/dlls/player.cpp b/dlls/player.cpp index 9680aaf6..1d198e84 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -826,6 +826,7 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit ) for( i = 0; i < MAX_AMMO_SLOTS; i++ ) m_rgAmmo[i] = 0; + DeactivateSatchels( this ); UpdateClientData(); // send Selected Weapon Message to our client From 004054586b0cc48863638a9505c3e139c3423148 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 10:01:32 +0500 Subject: [PATCH 070/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/52209adc339fa21ee1c9564e5d82ad97d9a09374 --- dlls/func_tank.cpp | 4 +++- dlls/player.cpp | 11 ----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/dlls/func_tank.cpp b/dlls/func_tank.cpp index ab295e0c..cace610d 100644 --- a/dlls/func_tank.cpp +++ b/dlls/func_tank.cpp @@ -351,6 +351,7 @@ BOOL CFuncTank::StartControl( CBasePlayer *pController ) ALERT( at_console, "using TANK!\n"); m_pController = pController; + m_pController->m_pTank = this; if( m_pController->m_pActiveItem ) { m_pController->m_pActiveItem->Holster(); @@ -380,6 +381,8 @@ void CFuncTank::StopControl() m_pController->m_iHideHUD &= ~HIDEHUD_WEAPONS; pev->nextthink = 0; + + m_pController->m_pTank = NULL; m_pController = NULL; if( IsActive() ) @@ -426,7 +429,6 @@ void CFuncTank::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use } else if( !m_pController && useType != USE_OFF ) { - ( (CBasePlayer*)pActivator )->m_pTank = this; StartControl( (CBasePlayer*)pActivator ); } else diff --git a/dlls/player.cpp b/dlls/player.cpp index 1d198e84..10216734 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -792,10 +792,7 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit ) m_pLastItem = NULL; if( m_pTank != 0 ) - { m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - } int i; CBasePlayerItem *pPendingItem; @@ -856,10 +853,7 @@ void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib ) g_pGameRules->PlayerKilled( this, pevAttacker, g_pevLastInflictor ); if( m_pTank != 0 ) - { m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - } // this client isn't going to be thinking for a while, so reset the sound until they respawn pSound = CSoundEnt::SoundPointerForIndex( CSoundEnt::ClientSoundIndex( edict() ) ); @@ -1402,10 +1396,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) m_pActiveItem->Holster(); if( m_pTank != 0 ) - { m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - } // clear out the suit message cache so we don't keep chattering SetSuitUpdate( NULL, FALSE, 0 ); @@ -1481,7 +1472,6 @@ void CBasePlayer::PlayerUse( void ) // Stop controlling the tank // TODO: Send HUD Update m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; return; } else @@ -2520,7 +2510,6 @@ void CBasePlayer::PostThink() { // they've moved off the platform m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; } } From 2b2fdac7d056587cc8105f47ea67cec457c913fa Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 10:04:33 +0500 Subject: [PATCH 071/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/336bc05c82c171f895656f913e9fbedfd8c8df54 --- dlls/rpg.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index 5fb8cc70..c87d345f 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -265,6 +265,11 @@ void CRpgRocket::FollowThink( void ) pev->velocity = pev->velocity * 0.2 + vecTarget * flSpeed * 0.798; if( pev->waterlevel == 0 && pev->velocity.Length() < 1500 ) { + if( m_pLauncher ) + { + // my launcher is still around, tell it I'm dead. + m_pLauncher->m_cActiveRockets--; + } Detonate(); } } From 6f8cd70328a9ec1ef1dc74ec07aed72e098f8fc9 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 10:11:39 +0500 Subject: [PATCH 072/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/7a627bf8e3e13929afd7b23ae8435ea8784b4654 --- dlls/satchel.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/dlls/satchel.cpp b/dlls/satchel.cpp index 458ac532..8ddc41a3 100644 --- a/dlls/satchel.cpp +++ b/dlls/satchel.cpp @@ -42,6 +42,9 @@ enum satchel_radio_e class CSatchelCharge : public CGrenade { + Vector m_lastBounceOrigin; // Used to fix a bug in engine: when object isn't moving, but its speed isn't 0 and on ground isn't set + void Spawn( void ); + void Precache( void ); void Spawn( void ); void Precache( void ); void BounceSound( void ); @@ -114,14 +117,19 @@ void CSatchelCharge::SatchelSlide( CBaseEntity *pOther ) } if( !( pev->flags & FL_ONGROUND ) && pev->velocity.Length2D() > 10 ) { + // Fix for a bug in engine: when object isn't moving, but its speed isn't 0 and on ground isn't set + if( pev->origin != m_lastBounceOrigin ) BounceSound(); } - StudioFrameAdvance(); + m_lastBounceOrigin = pev->origin; + // There is no model animation so commented this out to prevent net traffic + // StudioFrameAdvance(); } void CSatchelCharge::SatchelThink( void ) { - StudioFrameAdvance(); + // There is no model animation so commented this out to prevent net traffic + // StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; if( !IsInWorld() ) @@ -149,7 +157,7 @@ void CSatchelCharge::SatchelThink( void ) void CSatchelCharge::Precache( void ) { - PRECACHE_MODEL( "models/grenade.mdl" ); + PRECACHE_MODEL( "models/w_satchel.mdl" ); PRECACHE_SOUND( "weapons/g_bounce1.wav" ); PRECACHE_SOUND( "weapons/g_bounce2.wav" ); PRECACHE_SOUND( "weapons/g_bounce3.wav" ); From 73a99df89420b7bf2939bdd0ddf53ad755ce8a3e Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 10:15:17 +0500 Subject: [PATCH 073/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/c66ee97ade72db0f63d1357d7a0760702a1c92e8 --- dlls/cbase.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dlls/cbase.cpp b/dlls/cbase.cpp index cdf9a00f..6009bfd5 100644 --- a/dlls/cbase.cpp +++ b/dlls/cbase.cpp @@ -441,9 +441,16 @@ edict_t *EHANDLE::Get( void ) edict_t *EHANDLE::Set( edict_t *pent ) { - m_pent = pent; - if( pent ) - m_serialnumber = m_pent->serialnumber; + if( pent ) + { + m_pent = pent; + m_serialnumber = m_pent->serialnumber; + } + else + { + m_pent = NULL; + m_serialnumber = 0; + } return pent; } From 38b223651533fd0ab984147f906e2fe174683eb9 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 12:01:53 +0500 Subject: [PATCH 074/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/ee1ec9d64f96ecce0ab144cd86b246f5e7b00555 --- dlls/player.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/dlls/player.cpp b/dlls/player.cpp index 10216734..e94f5588 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -2583,11 +2583,10 @@ void CBasePlayer::PostThink() CheckPowerups( pev ); UpdatePlayerSound(); - +pt_end: // Track button info so we can detect 'pressed' and 'released' buttons next frame m_afButtonLast = pev->button; -pt_end: #if defined( CLIENT_WEAPONS ) // Decay timers on weapons // go through all of the weapons and make a list of the ones to pack @@ -4061,6 +4060,52 @@ void CBasePlayer::UpdateClientData( void ) m_rgpPlayerItems[i]->UpdateClientData( this ); } + if( m_pClientActiveItem != pPlayer->m_pActiveItem ) + { + if( pPlayer->m_pActiveItem == NULL ) + { + // If no weapon, we have to send update here + CBasePlayer *plr; + for( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + plr = (CBasePlayer *)UTIL_PlayerByIndex( i ); + if( !plr || !plr->IsObserver() || plr->m_hObserverTarget != pPlayer ) + continue; + + MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, plr->pev ); + WRITE_BYTE( 0 ); + WRITE_BYTE( 0 ); + WRITE_BYTE( 0 ); + MESSAGE_END(); + } + + MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pPlayer->pev ); + WRITE_BYTE( 0 ); + WRITE_BYTE( 0 ); + WRITE_BYTE( 0 ); + MESSAGE_END(); + } + else if( this != pPlayer ) + { + // Special case for spectator + CBasePlayerWeapon *gun = (CBasePlayerWeapon *)pPlayer->m_pActiveItem->GetWeaponPtr(); + if( gun ) + { + int state; + if( pPlayer->m_fOnTarget ) + state = WEAPON_IS_ONTARGET; + else + state = 1; + + MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); + WRITE_BYTE( state ); + WRITE_BYTE( gun->m_iId ); + WRITE_BYTE( gun->m_iClip ); + MESSAGE_END(); + } + } + } + // Cache and client weapon change m_pClientActiveItem = m_pActiveItem; m_iClientFOV = m_iFOV; From f318cab1c23d0060c36786763bc6d8c955745616 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 12:06:26 +0500 Subject: [PATCH 075/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/d8daa2f16c30f31f2839fae03580dd213e4501c4 --- dlls/shotgun.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/shotgun.cpp b/dlls/shotgun.cpp index 12e73ede..a08770b3 100644 --- a/dlls/shotgun.cpp +++ b/dlls/shotgun.cpp @@ -144,6 +144,9 @@ void CShotgun::PrimaryAttack() #endif m_pPlayer->pev->effects = (int)( m_pPlayer->pev->effects ) | EF_MUZZLEFLASH; + // player "shoot" animation + m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); + Vector vecSrc = m_pPlayer->GetGunPosition(); Vector vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES ); From 0570769d35c39a8c4d6a249ac7b46bd5fb0a5b8f Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 12:17:26 +0500 Subject: [PATCH 076/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/fd29683101f725c5aa41d6fb62d5217db45e8582 --- dlls/func_tank.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dlls/func_tank.cpp b/dlls/func_tank.cpp index cace610d..4ee4e6d6 100644 --- a/dlls/func_tank.cpp +++ b/dlls/func_tank.cpp @@ -369,6 +369,9 @@ BOOL CFuncTank::StartControl( CBasePlayer *pController ) void CFuncTank::StopControl() { + if( m_pLaser ) + m_pLaser->TurnOff(); + // TODO: bring back the controllers current weapon if( !m_pController ) return; From 075fd2903075aaa28b0d4930d7d1ba0d1b73f492 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 12:56:33 +0500 Subject: [PATCH 077/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/29c4d46ad02492a33ddd9bb4ace0c873855eebe7 --- dlls/items.cpp | 1 + dlls/weapons.cpp | 12 +++--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/dlls/items.cpp b/dlls/items.cpp index d9cc7871..b0b2aa38 100644 --- a/dlls/items.cpp +++ b/dlls/items.cpp @@ -166,6 +166,7 @@ void CItem::Materialize( void ) } SetTouch( &CItem::ItemTouch ); + SetThink( NULL ); } #define SF_SUIT_SHORTLOGON 0x0001 diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 61b038c0..22b4a456 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -485,7 +485,7 @@ void CBasePlayerItem::Materialize( void ) pev->solid = SOLID_TRIGGER; UTIL_SetOrigin( pev, pev->origin );// link into world. - SetTouch( &CBasePlayerItem::DefaultTouch); + SetTouch( &CBasePlayerItem::DefaultTouch ); SetThink( NULL ); } @@ -578,13 +578,6 @@ void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) } SUB_UseTargets( pOther, USE_TOGGLE, 0 ); // UNDONE: when should this happen? - - // If the item is falling and its Think remains FallItem after the player picks it up, - // then after the item touches the ground its Touch will be set back to DefaultTouch, - // so the player will pick it up again, this time Kill-ing the item (since we already have it in the inventory), - // which will make the pointer bad and crash the game. - if( m_pfnThink == &CBasePlayerItem::FallThink ) - SetThink( NULL ); } BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted ) @@ -734,7 +727,7 @@ void CBasePlayerItem::AttachToPlayer( CBasePlayer *pPlayer ) pev->modelindex = 0;// server won't send down to clients if modelindex == 0 pev->model = iStringNull; pev->owner = pPlayer->edict(); - pev->nextthink = gpGlobals->time + .1; + pev->nextthink = 0;// Remove think - prevents futher attempts to materialize SetTouch( NULL ); SetThink( NULL ); } @@ -1054,6 +1047,7 @@ void CBasePlayerAmmo::Materialize( void ) } SetTouch( &CBasePlayerAmmo::DefaultTouch ); + SetThink( NULL ); } void CBasePlayerAmmo::DefaultTouch( CBaseEntity *pOther ) From 5a2dccb978a7484db890c91f1ebd6fcfb9780194 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 12:58:28 +0500 Subject: [PATCH 078/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/09a90f4a0095d6702f43c66ff27e9f4444866f3c --- dlls/player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/player.cpp b/dlls/player.cpp index e94f5588..e9ad5645 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -799,13 +799,13 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit ) for( i = 0; i < MAX_ITEM_TYPES; i++ ) { m_pActiveItem = m_rgpPlayerItems[i]; + m_rgpPlayerItems[i] = NULL; while( m_pActiveItem ) { pPendingItem = m_pActiveItem->m_pNext; m_pActiveItem->Drop(); m_pActiveItem = pPendingItem; } - m_rgpPlayerItems[i] = NULL; } m_pActiveItem = NULL; From 7e5145aaff6dbb0d734acb66a97c9e7247e21402 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 13:03:38 +0500 Subject: [PATCH 079/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/b15a0f9d564d6f8e793617ebc88b41cd6940d90c --- dlls/crowbar.cpp | 12 ++++++++++++ dlls/glock.cpp | 12 ++++++++++++ dlls/weapons.h | 6 ++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index 98808e14..f9a91978 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -80,6 +80,18 @@ int CCrowbar::GetItemInfo( ItemInfo *p ) return 1; } +int CCrowbar::AddToPlayer( CBasePlayer *pPlayer ) +{ + if( CBasePlayerWeapon::AddToPlayer( pPlayer ) ) + { + MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev ); + WRITE_BYTE( m_iId ); + MESSAGE_END(); + return TRUE; + } + return FALSE; +} + BOOL CCrowbar::Deploy() { return DefaultDeploy( "models/v_crowbar.mdl", "models/p_crowbar.mdl", CROWBAR_DRAW, "crowbar" ); diff --git a/dlls/glock.cpp b/dlls/glock.cpp index 3eb08d6c..1150d8b9 100644 --- a/dlls/glock.cpp +++ b/dlls/glock.cpp @@ -86,6 +86,18 @@ int CGlock::GetItemInfo( ItemInfo *p ) return 1; } +int CGlock::AddToPlayer( CBasePlayer *pPlayer ) +{ + if( CBasePlayerWeapon::AddToPlayer( pPlayer ) ) + { + MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev ); + WRITE_BYTE( m_iId ); + MESSAGE_END(); + return TRUE; + } + return FALSE; +} + BOOL CGlock::Deploy() { // pev->body = 1; diff --git a/dlls/weapons.h b/dlls/weapons.h index 3d8dd6ad..f48767c8 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -463,7 +463,8 @@ public: void Spawn( void ); void Precache( void ); int iItemSlot( void ) { return 2; } - int GetItemInfo(ItemInfo *p); + int GetItemInfo( ItemInfo *p ); + int AddToPlayer( CBasePlayer *pPlayer ); void PrimaryAttack( void ); void SecondaryAttack( void ); @@ -496,7 +497,8 @@ public: int iItemSlot( void ) { return 1; } void EXPORT SwingAgain( void ); void EXPORT Smack( void ); - int GetItemInfo(ItemInfo *p); + int GetItemInfo( ItemInfo *p ); + int AddToPlayer( CBasePlayer *pPlayer ); void PrimaryAttack( void ); int Swing( int fFirst ); From 0af3a37151614429c13035c5dce0de3cf54f63c4 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 17 Jul 2017 13:45:39 +0500 Subject: [PATCH 080/211] Fix build. Remove unneeded changes. --- dlls/func_tank.cpp | 4 ++-- dlls/player.cpp | 4 ++-- dlls/rpg.cpp | 5 ----- dlls/satchel.cpp | 2 -- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/dlls/func_tank.cpp b/dlls/func_tank.cpp index 4ee4e6d6..54f4755a 100644 --- a/dlls/func_tank.cpp +++ b/dlls/func_tank.cpp @@ -369,8 +369,8 @@ BOOL CFuncTank::StartControl( CBasePlayer *pController ) void CFuncTank::StopControl() { - if( m_pLaser ) - m_pLaser->TurnOff(); + //if( m_pLaser ) + //m_pLaser->TurnOff(); // TODO: bring back the controllers current weapon if( !m_pController ) diff --git a/dlls/player.cpp b/dlls/player.cpp index e9ad5645..d8ed7010 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -4060,7 +4060,7 @@ void CBasePlayer::UpdateClientData( void ) m_rgpPlayerItems[i]->UpdateClientData( this ); } - if( m_pClientActiveItem != pPlayer->m_pActiveItem ) + /*if( m_pClientActiveItem != pPlayer->m_pActiveItem ) { if( pPlayer->m_pActiveItem == NULL ) { @@ -4104,7 +4104,7 @@ void CBasePlayer::UpdateClientData( void ) MESSAGE_END(); } } - } + }*/ // Cache and client weapon change m_pClientActiveItem = m_pActiveItem; diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index c87d345f..5fb8cc70 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -265,11 +265,6 @@ void CRpgRocket::FollowThink( void ) pev->velocity = pev->velocity * 0.2 + vecTarget * flSpeed * 0.798; if( pev->waterlevel == 0 && pev->velocity.Length() < 1500 ) { - if( m_pLauncher ) - { - // my launcher is still around, tell it I'm dead. - m_pLauncher->m_cActiveRockets--; - } Detonate(); } } diff --git a/dlls/satchel.cpp b/dlls/satchel.cpp index 8ddc41a3..015b3483 100644 --- a/dlls/satchel.cpp +++ b/dlls/satchel.cpp @@ -43,8 +43,6 @@ enum satchel_radio_e class CSatchelCharge : public CGrenade { Vector m_lastBounceOrigin; // Used to fix a bug in engine: when object isn't moving, but its speed isn't 0 and on ground isn't set - void Spawn( void ); - void Precache( void ); void Spawn( void ); void Precache( void ); void BounceSound( void ); From 8bae5a5450e7f0c1040fb7c2329a92723a9fc584 Mon Sep 17 00:00:00 2001 From: mittorn Date: Tue, 18 Jul 2017 12:59:46 +0000 Subject: [PATCH 081/211] Fix infinite loop on mingw --- cl_dll/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl_dll/Android.mk b/cl_dll/Android.mk index 94489844..ecbae657 100755 --- a/cl_dll/Android.mk +++ b/cl_dll/Android.mk @@ -91,7 +91,7 @@ SRCS+=./input_xash3d.cpp SRCS+=./scoreboard.cpp SRCS+=./MOTD.cpp INCLUDES = -I../common -I. -I../game_shared -I../pm_shared -I../engine -I../dlls -DEFINES = -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w +DEFINES = -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \ $(LOCAL_PATH)/../common \ From 5dab1c1f1db1556a6648f3c66e1066888257ae51 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 18 Jul 2017 22:54:03 +0500 Subject: [PATCH 082/211] Revert "Merge https://github.com/LevShisterov/BugfixedHL/commit/29c4d46ad02492a33ddd9bb4ace0c873855eebe7" This reverts commit 075fd2903075aaa28b0d4930d7d1ba0d1b73f492. --- dlls/items.cpp | 1 - dlls/weapons.cpp | 12 +++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/dlls/items.cpp b/dlls/items.cpp index b0b2aa38..d9cc7871 100644 --- a/dlls/items.cpp +++ b/dlls/items.cpp @@ -166,7 +166,6 @@ void CItem::Materialize( void ) } SetTouch( &CItem::ItemTouch ); - SetThink( NULL ); } #define SF_SUIT_SHORTLOGON 0x0001 diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 22b4a456..61b038c0 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -485,7 +485,7 @@ void CBasePlayerItem::Materialize( void ) pev->solid = SOLID_TRIGGER; UTIL_SetOrigin( pev, pev->origin );// link into world. - SetTouch( &CBasePlayerItem::DefaultTouch ); + SetTouch( &CBasePlayerItem::DefaultTouch); SetThink( NULL ); } @@ -578,6 +578,13 @@ void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) } SUB_UseTargets( pOther, USE_TOGGLE, 0 ); // UNDONE: when should this happen? + + // If the item is falling and its Think remains FallItem after the player picks it up, + // then after the item touches the ground its Touch will be set back to DefaultTouch, + // so the player will pick it up again, this time Kill-ing the item (since we already have it in the inventory), + // which will make the pointer bad and crash the game. + if( m_pfnThink == &CBasePlayerItem::FallThink ) + SetThink( NULL ); } BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted ) @@ -727,7 +734,7 @@ void CBasePlayerItem::AttachToPlayer( CBasePlayer *pPlayer ) pev->modelindex = 0;// server won't send down to clients if modelindex == 0 pev->model = iStringNull; pev->owner = pPlayer->edict(); - pev->nextthink = 0;// Remove think - prevents futher attempts to materialize + pev->nextthink = gpGlobals->time + .1; SetTouch( NULL ); SetThink( NULL ); } @@ -1047,7 +1054,6 @@ void CBasePlayerAmmo::Materialize( void ) } SetTouch( &CBasePlayerAmmo::DefaultTouch ); - SetThink( NULL ); } void CBasePlayerAmmo::DefaultTouch( CBaseEntity *pOther ) From 6d2a869ecdd0bc10b17733b78651c5528a099ec7 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 18 Jul 2017 22:56:45 +0500 Subject: [PATCH 083/211] Revert unneeded changes. --- dlls/satchel.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dlls/satchel.cpp b/dlls/satchel.cpp index 015b3483..aeb9c5e6 100644 --- a/dlls/satchel.cpp +++ b/dlls/satchel.cpp @@ -117,17 +117,15 @@ void CSatchelCharge::SatchelSlide( CBaseEntity *pOther ) { // Fix for a bug in engine: when object isn't moving, but its speed isn't 0 and on ground isn't set if( pev->origin != m_lastBounceOrigin ) - BounceSound(); + BounceSound(); } m_lastBounceOrigin = pev->origin; - // There is no model animation so commented this out to prevent net traffic - // StudioFrameAdvance(); + StudioFrameAdvance(); } void CSatchelCharge::SatchelThink( void ) { - // There is no model animation so commented this out to prevent net traffic - // StudioFrameAdvance(); + StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; if( !IsInWorld() ) From c8ebe744c3311f1306f88fd88a467abd57029de5 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 19 Jul 2017 02:00:03 +0500 Subject: [PATCH 084/211] Fix my mistakes. Apply fixes for rpg and tank laser again. --- dlls/func_tank.cpp | 11 +++++++++-- dlls/player.cpp | 46 ---------------------------------------------- dlls/rpg.cpp | 5 +++++ 3 files changed, 14 insertions(+), 48 deletions(-) diff --git a/dlls/func_tank.cpp b/dlls/func_tank.cpp index 54f4755a..c4e3cb42 100644 --- a/dlls/func_tank.cpp +++ b/dlls/func_tank.cpp @@ -93,6 +93,7 @@ public: BOOL StartControl( CBasePlayer* pController ); void StopControl( void ); void ControllerPostFrame( void ); + virtual void StopFire( void ){} protected: CBasePlayer* m_pController; @@ -369,8 +370,7 @@ BOOL CFuncTank::StartControl( CBasePlayer *pController ) void CFuncTank::StopControl() { - //if( m_pLaser ) - //m_pLaser->TurnOff(); + StopFire(); // TODO: bring back the controllers current weapon if( !m_pController ) @@ -755,6 +755,7 @@ public: virtual int Save( CSave &save ); virtual int Restore( CRestore &restore ); static TYPEDESCRIPTION m_SaveData[]; + virtual void StopFire( void ); private: CLaser *m_pLaser; @@ -859,6 +860,12 @@ void CFuncTankLaser::Fire( const Vector &barrelEnd, const Vector &forward, entva } } +void CFuncTankLaser::StopFire( void ) +{ + if( m_pLaser ) + m_pLaser->TurnOff(); +} + class CFuncTankRocket : public CFuncTank { public: diff --git a/dlls/player.cpp b/dlls/player.cpp index d8ed7010..04da24c4 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -4060,52 +4060,6 @@ void CBasePlayer::UpdateClientData( void ) m_rgpPlayerItems[i]->UpdateClientData( this ); } - /*if( m_pClientActiveItem != pPlayer->m_pActiveItem ) - { - if( pPlayer->m_pActiveItem == NULL ) - { - // If no weapon, we have to send update here - CBasePlayer *plr; - for( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - plr = (CBasePlayer *)UTIL_PlayerByIndex( i ); - if( !plr || !plr->IsObserver() || plr->m_hObserverTarget != pPlayer ) - continue; - - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, plr->pev ); - WRITE_BYTE( 0 ); - WRITE_BYTE( 0 ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - } - - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pPlayer->pev ); - WRITE_BYTE( 0 ); - WRITE_BYTE( 0 ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - } - else if( this != pPlayer ) - { - // Special case for spectator - CBasePlayerWeapon *gun = (CBasePlayerWeapon *)pPlayer->m_pActiveItem->GetWeaponPtr(); - if( gun ) - { - int state; - if( pPlayer->m_fOnTarget ) - state = WEAPON_IS_ONTARGET; - else - state = 1; - - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); - WRITE_BYTE( state ); - WRITE_BYTE( gun->m_iId ); - WRITE_BYTE( gun->m_iClip ); - MESSAGE_END(); - } - } - }*/ - // Cache and client weapon change m_pClientActiveItem = m_pActiveItem; m_iClientFOV = m_iFOV; diff --git a/dlls/rpg.cpp b/dlls/rpg.cpp index 5fb8cc70..fe1fd8a9 100644 --- a/dlls/rpg.cpp +++ b/dlls/rpg.cpp @@ -265,6 +265,11 @@ void CRpgRocket::FollowThink( void ) pev->velocity = pev->velocity * 0.2 + vecTarget * flSpeed * 0.798; if( pev->waterlevel == 0 && pev->velocity.Length() < 1500 ) { + if( CRpg *pLauncher = (CRpg*)( (CBaseEntity*)( m_hLauncher ) ) ) + { + // my launcher is still around, tell it I'm dead. + pLauncher->m_cActiveRockets--; + } Detonate(); } } From c2a1b013c2d7c9a9c3cb4268de52aa67e3cc2368 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 19 Jul 2017 02:47:31 +0500 Subject: [PATCH 085/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/001e6a09fa9e016995d76aa9092a7656efb63b9e --- dlls/weapons.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 61b038c0..8a7898bf 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -295,6 +295,7 @@ void W_Precache( void ) // common world objects UTIL_PrecacheOther( "item_suit" ); + UTIL_PrecacheOther( "item_healthkit" ); UTIL_PrecacheOther( "item_battery" ); UTIL_PrecacheOther( "item_antidote" ); UTIL_PrecacheOther( "item_security" ); @@ -316,6 +317,9 @@ void W_Precache( void ) UTIL_PrecacheOther( "ammo_9mmAR" ); UTIL_PrecacheOther( "ammo_ARgrenades" ); + // 9mm ammo box + UTIL_PrecacheOther( "ammo_9mmbox" ); + #if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD ) // python UTIL_PrecacheOtherWeapon( "weapon_357" ); From 9dff875d32bd076a34ce379f3e785fa7636bf228 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 19 Jul 2017 02:51:17 +0500 Subject: [PATCH 086/211] Revert "Revert unneeded changes." This reverts commit 6d2a869ecdd0bc10b17733b78651c5528a099ec7. --- dlls/satchel.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dlls/satchel.cpp b/dlls/satchel.cpp index aeb9c5e6..015b3483 100644 --- a/dlls/satchel.cpp +++ b/dlls/satchel.cpp @@ -117,15 +117,17 @@ void CSatchelCharge::SatchelSlide( CBaseEntity *pOther ) { // Fix for a bug in engine: when object isn't moving, but its speed isn't 0 and on ground isn't set if( pev->origin != m_lastBounceOrigin ) - BounceSound(); + BounceSound(); } m_lastBounceOrigin = pev->origin; - StudioFrameAdvance(); + // There is no model animation so commented this out to prevent net traffic + // StudioFrameAdvance(); } void CSatchelCharge::SatchelThink( void ) { - StudioFrameAdvance(); + // There is no model animation so commented this out to prevent net traffic + // StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; if( !IsInWorld() ) From 426a0e7ab31ece52abe20436a64f4a5ce838bfe9 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 19 Jul 2017 02:52:11 +0500 Subject: [PATCH 087/211] Revert "Revert "Merge https://github.com/LevShisterov/BugfixedHL/commit/29c4d46ad02492a33ddd9bb4ace0c873855eebe7"" This reverts commit 5dab1c1f1db1556a6648f3c66e1066888257ae51. --- dlls/items.cpp | 1 + dlls/weapons.cpp | 12 +++--------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/dlls/items.cpp b/dlls/items.cpp index d9cc7871..b0b2aa38 100644 --- a/dlls/items.cpp +++ b/dlls/items.cpp @@ -166,6 +166,7 @@ void CItem::Materialize( void ) } SetTouch( &CItem::ItemTouch ); + SetThink( NULL ); } #define SF_SUIT_SHORTLOGON 0x0001 diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 8a7898bf..05db43da 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -489,7 +489,7 @@ void CBasePlayerItem::Materialize( void ) pev->solid = SOLID_TRIGGER; UTIL_SetOrigin( pev, pev->origin );// link into world. - SetTouch( &CBasePlayerItem::DefaultTouch); + SetTouch( &CBasePlayerItem::DefaultTouch ); SetThink( NULL ); } @@ -582,13 +582,6 @@ void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) } SUB_UseTargets( pOther, USE_TOGGLE, 0 ); // UNDONE: when should this happen? - - // If the item is falling and its Think remains FallItem after the player picks it up, - // then after the item touches the ground its Touch will be set back to DefaultTouch, - // so the player will pick it up again, this time Kill-ing the item (since we already have it in the inventory), - // which will make the pointer bad and crash the game. - if( m_pfnThink == &CBasePlayerItem::FallThink ) - SetThink( NULL ); } BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted ) @@ -738,7 +731,7 @@ void CBasePlayerItem::AttachToPlayer( CBasePlayer *pPlayer ) pev->modelindex = 0;// server won't send down to clients if modelindex == 0 pev->model = iStringNull; pev->owner = pPlayer->edict(); - pev->nextthink = gpGlobals->time + .1; + pev->nextthink = 0;// Remove think - prevents futher attempts to materialize SetTouch( NULL ); SetThink( NULL ); } @@ -1058,6 +1051,7 @@ void CBasePlayerAmmo::Materialize( void ) } SetTouch( &CBasePlayerAmmo::DefaultTouch ); + SetThink( NULL ); } void CBasePlayerAmmo::DefaultTouch( CBaseEntity *pOther ) From 51c682c15e7d6e2abdf403ef096b9cecbd545211 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 19 Jul 2017 03:22:08 +0500 Subject: [PATCH 088/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/adb616153729102975800edbbdcc8ed8a50ed8ad --- dlls/game.cpp | 4 +++- dlls/game.h | 1 + dlls/gauss.cpp | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dlls/game.cpp b/dlls/game.cpp index 9b69cac9..b109f376 100644 --- a/dlls/game.cpp +++ b/dlls/game.cpp @@ -25,11 +25,12 @@ cvar_t timeleft = { "mp_timeleft","0" , FCVAR_SERVER | FCVAR_UNLOGGED }; // " // multiplayer server rules cvar_t teamplay = { "mp_teamplay","0", FCVAR_SERVER }; -cvar_t fraglimit = {"mp_fraglimit","0", FCVAR_SERVER }; +cvar_t fraglimit = { "mp_fraglimit","0", FCVAR_SERVER }; cvar_t timelimit = { "mp_timelimit","0", FCVAR_SERVER }; cvar_t friendlyfire = { "mp_friendlyfire","0", FCVAR_SERVER }; cvar_t falldamage = { "mp_falldamage","0", FCVAR_SERVER }; cvar_t weaponstay = { "mp_weaponstay","0", FCVAR_SERVER }; +cvar_t selfgauss = { "mp_selfgauss", "1", FCVAR_SERVER }; cvar_t forcerespawn = { "mp_forcerespawn","1", FCVAR_SERVER }; cvar_t flashlight = { "mp_flashlight","0", FCVAR_SERVER }; cvar_t aimcrosshair = { "mp_autocrosshair","1", FCVAR_SERVER }; @@ -467,6 +468,7 @@ void GameDLLInit( void ) CVAR_REGISTER( &friendlyfire ); CVAR_REGISTER( &falldamage ); CVAR_REGISTER( &weaponstay ); + CVAR_REGISTER( &selfgauss ); CVAR_REGISTER( &forcerespawn ); CVAR_REGISTER( &flashlight ); CVAR_REGISTER( &aimcrosshair ); diff --git a/dlls/game.h b/dlls/game.h index 925010f3..e29b2563 100644 --- a/dlls/game.h +++ b/dlls/game.h @@ -27,6 +27,7 @@ extern cvar_t timelimit; extern cvar_t friendlyfire; extern cvar_t falldamage; extern cvar_t weaponstay; +extern cvar_t selfgauss; extern cvar_t forcerespawn; extern cvar_t flashlight; extern cvar_t aimcrosshair; diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index d3e005c2..62af08e1 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -24,6 +24,7 @@ #include "soundent.h" #include "shake.h" #include "gamerules.h" +#include "game.h" #define GAUSS_PRIMARY_CHARGE_VOLUME 256// how loud gauss is while charging #define GAUSS_PRIMARY_FIRE_VOLUME 450// how loud gauss is when discharged @@ -512,6 +513,10 @@ void CGauss::Fire( Vector vecOrigSrc, Vector vecDir, float flDamage ) vecSrc = beam_tr.vecEndPos + vecDir; } + else if( !selfgauss.value ) + { + flDamage = 0; + } } else { From 946e962f3c8e1429ab39a0e5e851ff5d1e13a211 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 19 Jul 2017 04:06:19 +0500 Subject: [PATCH 089/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/1c71f33cb0978cfdcfc5167d9c8860654778f762 --- cl_dll/flashlight.cpp | 2 ++ dlls/player.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/cl_dll/flashlight.cpp b/cl_dll/flashlight.cpp index 8b8a8d0e..c3514c7d 100644 --- a/cl_dll/flashlight.cpp +++ b/cl_dll/flashlight.cpp @@ -49,6 +49,8 @@ void CHudFlashlight::Reset( void ) { m_fFade = 0; m_fOn = 0; + m_iBat = 100; + m_flBat = 1.0; } int CHudFlashlight::VidInit( void ) diff --git a/dlls/player.cpp b/dlls/player.cpp index 04da24c4..0d86caf8 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -3868,6 +3868,12 @@ void CBasePlayer::UpdateClientData( void ) FireTargets( "game_playerspawn", this, this, USE_TOGGLE, 0 ); + // Send flashlight status + MESSAGE_BEGIN( MSG_ONE, gmsgFlashlight, NULL, pev ); + WRITE_BYTE( FlashlightIsOn() ? 1 : 0 ); + WRITE_BYTE( m_iFlashBattery ); + MESSAGE_END(); + InitStatusBar(); } From a2e4a7ec03d987c0645742fde30a591452689245 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 19 Jul 2017 04:11:08 +0500 Subject: [PATCH 090/211] Fix crosshair. --- cl_dll/ammo.cpp | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index f439520e..edc21652 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -305,6 +305,9 @@ void CHudAmmo::Reset( void ) gHR.Reset(); //VidInit(); + wrect_t nullrc = {}; + SetCrosshair( 0, nullrc, 0, 0, 0 ); // reset crosshair + m_pWeapon = NULL; // reset last weapon } int CHudAmmo::VidInit( void ) @@ -606,22 +609,24 @@ int CHudAmmo::MsgFunc_CurWeapon( const char *pszName, int iSize, void *pbuf ) m_pWeapon = pWeapon; - if( gHUD.m_iFOV >= 90 ) + if( !( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) ) { - // normal crosshairs - if( fOnTarget && m_pWeapon->hAutoaim ) - SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255 ); + if( gHUD.m_iFOV >= 90 ) + { + // normal crosshairs + if( fOnTarget && m_pWeapon->hAutoaim ) + SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255 ); + else + SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 ); + } else - SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 ); - } - else - { - // zoomed crosshairs - if( fOnTarget && m_pWeapon->hZoomedAutoaim ) - SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255 ); - else - SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255 ); - + { + // zoomed crosshairs + if( fOnTarget && m_pWeapon->hZoomedAutoaim ) + SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255 ); + else + SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255 ); + } } m_fFade = 200.0f; //!!! From d062757f5273e0ecdbf05f6a1ea599690ba8816a Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 19 Jul 2017 23:25:47 +0500 Subject: [PATCH 091/211] Use MAKE_STRING for literals. Remove duplicated code. --- dlls/bmodels.cpp | 40 ++++------ dlls/buttons.cpp | 10 +-- dlls/doors.cpp | 192 +++++++++++++++++++++------------------------- dlls/maprules.cpp | 160 +++++++++++++++++++------------------- dlls/plats.cpp | 119 ++++++++++++++-------------- dlls/triggers.cpp | 2 +- 6 files changed, 244 insertions(+), 279 deletions(-) diff --git a/dlls/bmodels.cpp b/dlls/bmodels.cpp index 6e8526f9..c48abbf9 100644 --- a/dlls/bmodels.cpp +++ b/dlls/bmodels.cpp @@ -430,15 +430,13 @@ void CFuncRotating::Spawn() void CFuncRotating::Precache( void ) { - char* szSoundFile = (char*)STRING( pev->message ); + const char* szSoundFile = STRING( pev->message ); + BOOL NullSound = FALSE; // set up fan sounds if( !FStringNull( pev->message ) && strlen( szSoundFile ) > 0 ) { // if a path is set for a wave, use it - PRECACHE_SOUND( szSoundFile ); - - pev->noiseRunning = ALLOC_STRING( szSoundFile ); } else { @@ -446,42 +444,32 @@ void CFuncRotating::Precache( void ) switch( m_sounds ) { case 1: - PRECACHE_SOUND( "fans/fan1.wav" ); - pev->noiseRunning = ALLOC_STRING( "fans/fan1.wav" ); + szSoundFile = "fans/fan1.wav"; break; case 2: - PRECACHE_SOUND( "fans/fan2.wav" ); - pev->noiseRunning = ALLOC_STRING( "fans/fan2.wav" ); + szSoundFile = "fans/fan2.wav"; break; case 3: - PRECACHE_SOUND( "fans/fan3.wav" ); - pev->noiseRunning = ALLOC_STRING( "fans/fan3.wav" ); + szSoundFile = "fans/fan3.wav"; break; case 4: - PRECACHE_SOUND( "fans/fan4.wav" ); - pev->noiseRunning = ALLOC_STRING( "fans/fan4.wav" ); + szSoundFile = "fans/fan4.wav"; break; case 5: - PRECACHE_SOUND( "fans/fan5.wav" ); - pev->noiseRunning = ALLOC_STRING( "fans/fan5.wav" ); + szSoundFile = "fans/fan5.wav"; break; case 0: default: - if( !FStringNull( pev->message ) && strlen( szSoundFile ) > 0 ) - { - PRECACHE_SOUND( szSoundFile ); - - pev->noiseRunning = ALLOC_STRING( szSoundFile ); - break; - } - else - { - pev->noiseRunning = ALLOC_STRING( "common/null.wav" ); - break; - } + szSoundFile = "common/null.wav"; + NullSound = TRUE; + break; } } + if( !NullSound ) + PRECACHE_SOUND( szSoundFile ); + pev->noiseRunning = MAKE_STRING( szSoundFile ); + if( pev->avelocity != g_vecZero ) { // if fan was spinning, and we went through transition or save/restore, diff --git a/dlls/buttons.cpp b/dlls/buttons.cpp index df7c51f3..7ea9082a 100644 --- a/dlls/buttons.cpp +++ b/dlls/buttons.cpp @@ -292,14 +292,14 @@ void CBaseButton::Precache( void ) { pszSound = ButtonSound( (int)m_bLockedSound ); PRECACHE_SOUND( pszSound ); - m_ls.sLockedSound = ALLOC_STRING( pszSound ); + m_ls.sLockedSound = MAKE_STRING( pszSound ); } if( m_bUnlockedSound ) { pszSound = ButtonSound( (int)m_bUnlockedSound ); PRECACHE_SOUND( pszSound ); - m_ls.sUnlockedSound = ALLOC_STRING( pszSound ); + m_ls.sUnlockedSound = MAKE_STRING( pszSound ); } // get sentence group names, for doors which are directly 'touched' to open @@ -469,7 +469,7 @@ void CBaseButton::Spawn() //---------------------------------------------------- pszSound = ButtonSound( m_sounds ); PRECACHE_SOUND( pszSound ); - pev->noise = ALLOC_STRING( pszSound ); + pev->noise = MAKE_STRING( pszSound ); Precache(); @@ -876,7 +876,7 @@ void CRotButton::Spawn( void ) //---------------------------------------------------- pszSound = ButtonSound( m_sounds ); PRECACHE_SOUND( pszSound ); - pev->noise = ALLOC_STRING( pszSound ); + pev->noise = MAKE_STRING( pszSound ); // set the axis of rotation CBaseToggle::AxisDir( pev ); @@ -1012,7 +1012,7 @@ void CMomentaryRotButton::Spawn( void ) const char *pszSound = ButtonSound( m_sounds ); PRECACHE_SOUND( pszSound ); - pev->noise = ALLOC_STRING( pszSound ); + pev->noise = MAKE_STRING( pszSound ); m_lastUsed = 0; } diff --git a/dlls/doors.cpp b/dlls/doors.cpp index 3a8613ab..ce901ee8 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -330,114 +330,104 @@ void CBaseDoor::SetToggleState( int state ) void CBaseDoor::Precache( void ) { const char *pszSound; + BOOL NullSound = FALSE; // set the door's "in-motion" sound switch( m_bMoveSnd ) { - case 0: - pev->noiseMoving = ALLOC_STRING( "common/null.wav" ); - break; case 1: - PRECACHE_SOUND( "doors/doormove1.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove1.wav" ); + pszSound = "doors/doormove1.wav"; break; case 2: - PRECACHE_SOUND( "doors/doormove2.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove2.wav" ); + pszSound = "doors/doormove2.wav"; break; case 3: - PRECACHE_SOUND( "doors/doormove3.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove3.wav" ); + pszSound = "doors/doormove3.wav"; break; case 4: - PRECACHE_SOUND( "doors/doormove4.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove4.wav" ); + pszSound = "doors/doormove4.wav"; break; case 5: - PRECACHE_SOUND( "doors/doormove5.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove5.wav" ); + pszSound = "doors/doormove5.wav"; break; case 6: - PRECACHE_SOUND( "doors/doormove6.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove6.wav" ); + pszSound = "doors/doormove6.wav"; break; case 7: - PRECACHE_SOUND( "doors/doormove7.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove7.wav" ); + pszSound = "doors/doormove7.wav"; break; case 8: - PRECACHE_SOUND( "doors/doormove8.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove8.wav" ); + pszSound = "doors/doormove8.wav"; break; case 9: - PRECACHE_SOUND( "doors/doormove9.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove9.wav" ); + pszSound = "doors/doormove9.wav"; break; case 10: - PRECACHE_SOUND( "doors/doormove10.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove10.wav" ); + pszSound = "doors/doormove10.wav"; break; + case 0: default: - pev->noiseMoving = ALLOC_STRING( "common/null.wav" ); + pszSound = "common/null.wav"; + NullSound = TRUE; break; } + if( !NullSound ) + PRECACHE_SOUND( pszSound ); + pev->noiseMoving = MAKE_STRING( pszSound ); + NullSound = FALSE; + // set the door's 'reached destination' stop sound switch( m_bStopSnd ) { - case 0: - pev->noiseArrived = ALLOC_STRING( "common/null.wav" ); - break; case 1: - PRECACHE_SOUND( "doors/doorstop1.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop1.wav" ); + pszSound = "doors/doorstop1.wav"; break; case 2: - PRECACHE_SOUND( "doors/doorstop2.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop2.wav" ); + pszSound = "doors/doorstop2.wav"; break; case 3: - PRECACHE_SOUND( "doors/doorstop3.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop3.wav" ); + pszSound = "doors/doorstop3.wav"; break; case 4: - PRECACHE_SOUND( "doors/doorstop4.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop4.wav" ); + pszSound = "doors/doorstop4.wav"; break; case 5: - PRECACHE_SOUND( "doors/doorstop5.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop5.wav" ); + pszSound = "doors/doorstop5.wav"; break; case 6: - PRECACHE_SOUND( "doors/doorstop6.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop6.wav"); + pszSound = "doors/doorstop6.wav" break; case 7: - PRECACHE_SOUND( "doors/doorstop7.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop7.wav" ); + pszSound = "doors/doorstop7.wav"; break; case 8: - PRECACHE_SOUND( "doors/doorstop8.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop8.wav" ); + pszSound = "doors/doorstop8.wav"; break; + case 0: default: - pev->noiseArrived = ALLOC_STRING( "common/null.wav" ); + pszSound = "common/null.wav"; + NullSound = TRUE; break; } + if( !NullSound ) + PRECACHE_SOUND( pszSound ); + pev->noiseArrived = MAKE_STRING( pszSound ); + // get door button sounds, for doors which are directly 'touched' to open if( m_bLockedSound ) { pszSound = ButtonSound( (int)m_bLockedSound ); PRECACHE_SOUND( pszSound ); - m_ls.sLockedSound = ALLOC_STRING( pszSound ); + m_ls.sLockedSound = MAKE_STRING( pszSound ); } if( m_bUnlockedSound ) { pszSound = ButtonSound( (int)m_bUnlockedSound ); PRECACHE_SOUND( pszSound ); - m_ls.sUnlockedSound = ALLOC_STRING( pszSound ); + m_ls.sUnlockedSound = MAKE_STRING( pszSound ); } // get sentence group names, for doors which are directly 'touched' to open @@ -445,39 +435,39 @@ void CBaseDoor::Precache( void ) { case 1: // access denied - m_ls.sLockedSentence = ALLOC_STRING( "NA" ); + m_ls.sLockedSentence = MAKE_STRING( "NA" ); break; case 2: // security lockout - m_ls.sLockedSentence = ALLOC_STRING( "ND" ); + m_ls.sLockedSentence = MAKE_STRING( "ND" ); break; case 3: // blast door - m_ls.sLockedSentence = ALLOC_STRING( "NF" ); + m_ls.sLockedSentence = MAKE_STRING( "NF" ); break; case 4: // fire door - m_ls.sLockedSentence = ALLOC_STRING( "NFIRE" ); + m_ls.sLockedSentence = MAKE_STRING( "NFIRE" ); break; case 5: // chemical door - m_ls.sLockedSentence = ALLOC_STRING( "NCHEM" ); + m_ls.sLockedSentence = MAKE_STRING( "NCHEM" ); break; case 6: // radiation door - m_ls.sLockedSentence = ALLOC_STRING( "NRAD" ); + m_ls.sLockedSentence = MAKE_STRING( "NRAD" ); break; case 7: // gen containment - m_ls.sLockedSentence = ALLOC_STRING( "NCON" ); + m_ls.sLockedSentence = MAKE_STRING( "NCON" ); break; case 8: // maintenance door - m_ls.sLockedSentence = ALLOC_STRING( "NH" ); + m_ls.sLockedSentence = MAKE_STRING( "NH" ); break; case 9: // broken door - m_ls.sLockedSentence = ALLOC_STRING( "NG" ); + m_ls.sLockedSentence = MAKE_STRING( "NG" ); break; default: m_ls.sLockedSentence = 0; @@ -488,35 +478,35 @@ void CBaseDoor::Precache( void ) { case 1: // access granted - m_ls.sUnlockedSentence = ALLOC_STRING( "EA" ); + m_ls.sUnlockedSentence = MAKE_STRING( "EA" ); break; case 2: // security door - m_ls.sUnlockedSentence = ALLOC_STRING( "ED" ); + m_ls.sUnlockedSentence = MAKE_STRING( "ED" ); break; case 3: // blast door - m_ls.sUnlockedSentence = ALLOC_STRING( "EF" ); + m_ls.sUnlockedSentence = MAKE_STRING( "EF" ); break; case 4: // fire door - m_ls.sUnlockedSentence = ALLOC_STRING( "EFIRE" ); + m_ls.sUnlockedSentence = MAKE_STRING( "EFIRE" ); break; case 5: // chemical door - m_ls.sUnlockedSentence = ALLOC_STRING( "ECHEM" ); + m_ls.sUnlockedSentence = MAKE_STRING( "ECHEM" ); break; case 6: // radiation door - m_ls.sUnlockedSentence = ALLOC_STRING( "ERAD" ); + m_ls.sUnlockedSentence = MAKE_STRING( "ERAD" ); break; case 7: // gen containment - m_ls.sUnlockedSentence = ALLOC_STRING( "ECON" ); + m_ls.sUnlockedSentence = MAKE_STRING( "ECON" ); break; case 8: // maintenance door - m_ls.sUnlockedSentence = ALLOC_STRING( "EH" ); + m_ls.sUnlockedSentence = MAKE_STRING( "EH" ); break; default: m_ls.sUnlockedSentence = 0; @@ -985,94 +975,88 @@ void CMomentaryDoor::Spawn( void ) Precache(); } - + void CMomentaryDoor::Precache( void ) { + const char *pszSound; + BOOL NullSound = FALSE; + // set the door's "in-motion" sound switch( m_bMoveSnd ) { - case 0: - pev->noiseMoving = ALLOC_STRING( "common/null.wav" ); - break; case 1: - PRECACHE_SOUND( "doors/doormove1.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove1.wav" ); + pszSound = "doors/doormove1.wav"; break; case 2: - PRECACHE_SOUND( "doors/doormove2.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove2.wav" ); + pszSound = "doors/doormove2.wav"; break; case 3: - PRECACHE_SOUND( "doors/doormove3.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove3.wav" ); + pszSound = "doors/doormove3.wav"; break; case 4: - PRECACHE_SOUND( "doors/doormove4.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove4.wav" ); + pszSound = "doors/doormove4.wav"; break; case 5: - PRECACHE_SOUND( "doors/doormove5.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove5.wav" ); + pszSound = "doors/doormove5.wav"; break; case 6: - PRECACHE_SOUND( "doors/doormove6.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove6.wav" ); + pszSound = "doors/doormove6.wav"; break; case 7: - PRECACHE_SOUND( "doors/doormove7.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove7.wav" ); + pszSound = "doors/doormove7.wav"; break; case 8: - PRECACHE_SOUND( "doors/doormove8.wav" ); - pev->noiseMoving = ALLOC_STRING( "doors/doormove8.wav" ); + pszSound = "doors/doormove8.wav"; break; + case 0: default: - pev->noiseMoving = ALLOC_STRING( "common/null.wav" ); + pszSound = "common/null.wav"; + NullSound = TRUE; break; } + if( !NullSound ) + PRECACHE_SOUND( pszSound ); + pev->noiseMoving = MAKE_STRING( pszSound ); + NullSound = FALSE; + // set the door's 'reached destination' stop sound switch( m_bStopSnd ) { - case 0: - pev->noiseArrived = ALLOC_STRING( "common/null.wav" ); - break; case 1: - PRECACHE_SOUND( "doors/doorstop1.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop1.wav" ); + pszSound = "doors/doorstop1.wav"; break; case 2: - PRECACHE_SOUND( "doors/doorstop2.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop2.wav" ); + pszSound = "doors/doorstop2.wav"; break; case 3: - PRECACHE_SOUND( "doors/doorstop3.wav" ); - pev->noiseArrived = ALLOC_STRING("doors/doorstop3.wav"); + pszSound = "doors/doorstop3.wav"; break; case 4: - PRECACHE_SOUND( "doors/doorstop4.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop4.wav" ); + pszSound = "doors/doorstop4.wav"; break; case 5: - PRECACHE_SOUND( "doors/doorstop5.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop5.wav" ); + pszSound = "doors/doorstop5.wav"; break; case 6: - PRECACHE_SOUND( "doors/doorstop6.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop6.wav" ); + pszSound = "doors/doorstop6.wav"; break; case 7: - PRECACHE_SOUND( "doors/doorstop7.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop7.wav" ); + pszSound = "doors/doorstop7.wav"; break; case 8: - PRECACHE_SOUND( "doors/doorstop8.wav" ); - pev->noiseArrived = ALLOC_STRING( "doors/doorstop8.wav" ); + pszSound = "doors/doorstop8.wav"; break; + case 0: default: - pev->noiseArrived = ALLOC_STRING( "common/null.wav" ); + pszSound = "common/null.wav"; + NullSound = TRUE; break; } + + if( !NullSound ) + PRECACHE_SOUND( pszSound ); + pev->noiseArrived = MAKE_STRING( pszSound ); } void CMomentaryDoor::KeyValue( KeyValueData *pkvd ) diff --git a/dlls/maprules.cpp b/dlls/maprules.cpp index 2230acac..bfec93e2 100644 --- a/dlls/maprules.cpp +++ b/dlls/maprules.cpp @@ -153,9 +153,9 @@ void CGameScore::Spawn( void ) void CGameScore::KeyValue( KeyValueData *pkvd ) { - if (FStrEq(pkvd->szKeyName, "points")) + if( FStrEq( pkvd->szKeyName, "points" ) ) { - SetPoints( atoi(pkvd->szValue) ); + SetPoints( atoi( pkvd->szValue ) ); pkvd->fHandled = TRUE; } else @@ -164,13 +164,13 @@ void CGameScore::KeyValue( KeyValueData *pkvd ) void CGameScore::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; // Only players can use this - if ( pActivator->IsPlayer() ) + if( pActivator->IsPlayer() ) { - if ( AwardToTeam() ) + if( AwardToTeam() ) { pActivator->AddPointsToTeam( Points(), AllowNegativeScore() ); } @@ -194,7 +194,7 @@ LINK_ENTITY_TO_CLASS( game_end, CGameEnd ) void CGameEnd::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; g_pGameRules->EndMultiplayerGame(); @@ -239,27 +239,27 @@ IMPLEMENT_SAVERESTORE( CGameText, CRulePointEntity ) void CGameText::KeyValue( KeyValueData *pkvd ) { - if (FStrEq(pkvd->szKeyName, "channel")) + if( FStrEq( pkvd->szKeyName, "channel" ) ) { m_textParms.channel = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "x")) + else if( FStrEq( pkvd->szKeyName, "x" ) ) { m_textParms.x = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "y")) + else if( FStrEq(pkvd->szKeyName, "y" ) ) { m_textParms.y = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "effect")) + else if( FStrEq( pkvd->szKeyName, "effect" ) ) { m_textParms.effect = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "color")) + else if( FStrEq( pkvd->szKeyName, "color" ) ) { int color[4]; UTIL_StringToIntArray( color, 4, pkvd->szValue ); @@ -269,7 +269,7 @@ void CGameText::KeyValue( KeyValueData *pkvd ) m_textParms.a1 = color[3]; pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "color2")) + else if( FStrEq( pkvd->szKeyName, "color2" ) ) { int color[4]; UTIL_StringToIntArray( color, 4, pkvd->szValue ); @@ -279,22 +279,22 @@ void CGameText::KeyValue( KeyValueData *pkvd ) m_textParms.a2 = color[3]; pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "fadein")) + else if( FStrEq( pkvd->szKeyName, "fadein" ) ) { m_textParms.fadeinTime = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "fadeout")) + else if( FStrEq( pkvd->szKeyName, "fadeout" ) ) { m_textParms.fadeoutTime = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "holdtime")) + else if( FStrEq( pkvd->szKeyName, "holdtime" ) ) { m_textParms.holdTime = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "fxtime")) + else if( FStrEq(pkvd->szKeyName, "fxtime" ) ) { m_textParms.fxTime = atof( pkvd->szValue ); pkvd->fHandled = TRUE; @@ -305,16 +305,16 @@ void CGameText::KeyValue( KeyValueData *pkvd ) void CGameText::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; - if ( MessageToAll() ) + if( MessageToAll() ) { UTIL_HudMessageAll( m_textParms, MessageGet() ); } else { - if ( pActivator->IsNetClient() ) + if( pActivator->IsNetClient() ) { UTIL_HudMessage( pActivator, m_textParms, MessageGet() ); } @@ -356,12 +356,12 @@ LINK_ENTITY_TO_CLASS( game_team_master, CGameTeamMaster ) void CGameTeamMaster::KeyValue( KeyValueData *pkvd ) { - if (FStrEq(pkvd->szKeyName, "teamindex")) + if( FStrEq( pkvd->szKeyName, "teamindex" ) ) { m_teamIndex = atoi( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "triggerstate")) + else if( FStrEq( pkvd->szKeyName, "triggerstate" ) ) { int type = atoi( pkvd->szValue ); switch( type ) @@ -384,12 +384,12 @@ void CGameTeamMaster::KeyValue( KeyValueData *pkvd ) void CGameTeamMaster::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; - if ( useType == USE_SET ) + if( useType == USE_SET ) { - if ( value < 0 ) + if( value < 0 ) { m_teamIndex = -1; } @@ -400,10 +400,10 @@ void CGameTeamMaster::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY return; } - if ( TeamMatch( pActivator ) ) + if( TeamMatch( pActivator ) ) { SUB_UseTargets( pActivator, triggerType, value ); - if ( RemoveOnFire() ) + if( RemoveOnFire() ) UTIL_Remove( this ); } } @@ -415,7 +415,7 @@ BOOL CGameTeamMaster::IsTriggered( CBaseEntity *pActivator ) const char *CGameTeamMaster::TeamID( void ) { - if ( m_teamIndex < 0 ) // Currently set to "no team" + if( m_teamIndex < 0 ) // Currently set to "no team" return ""; return g_pGameRules->GetIndexedTeamName( m_teamIndex ); // UNDONE: Fill this in with the team from the "teamlist" @@ -423,10 +423,10 @@ const char *CGameTeamMaster::TeamID( void ) BOOL CGameTeamMaster::TeamMatch( CBaseEntity *pActivator ) { - if ( m_teamIndex < 0 && AnyTeam() ) + if( m_teamIndex < 0 && AnyTeam() ) return TRUE; - if ( !pActivator ) + if( !pActivator ) return FALSE; return UTIL_TeamsMatch( pActivator->TeamID(), TeamID() ); @@ -443,7 +443,7 @@ BOOL CGameTeamMaster::TeamMatch( CBaseEntity *pActivator ) class CGameTeamSet : public CRulePointEntity { public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_TEAMSET_FIREONCE) ? TRUE : FALSE; } inline BOOL ShouldClearTeam( void ) { return (pev->spawnflags & SF_TEAMSET_CLEARTEAM) ? TRUE : FALSE; } @@ -454,10 +454,10 @@ LINK_ENTITY_TO_CLASS( game_team_set, CGameTeamSet ) void CGameTeamSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; - if ( ShouldClearTeam() ) + if( ShouldClearTeam() ) { SUB_UseTargets( pActivator, USE_SET, -1 ); } @@ -466,7 +466,7 @@ void CGameTeamSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE SUB_UseTargets( pActivator, USE_SET, 0 ); } - if ( RemoveOnFire() ) + if( RemoveOnFire() ) { UTIL_Remove( this ); } @@ -506,22 +506,22 @@ IMPLEMENT_SAVERESTORE( CGamePlayerZone, CRuleBrushEntity ) void CGamePlayerZone::KeyValue( KeyValueData *pkvd ) { - if (FStrEq(pkvd->szKeyName, "intarget")) + if( FStrEq(pkvd->szKeyName, "intarget" ) ) { m_iszInTarget = ALLOC_STRING( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "outtarget")) + else if( FStrEq( pkvd->szKeyName, "outtarget" ) ) { m_iszOutTarget = ALLOC_STRING( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "incount")) + else if( FStrEq( pkvd->szKeyName, "incount" ) ) { m_iszInCount = ALLOC_STRING( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "outcount")) + else if( FStrEq( pkvd->szKeyName, "outcount" ) ) { m_iszOutCount = ALLOC_STRING( pkvd->szValue ); pkvd->fHandled = TRUE; @@ -535,12 +535,12 @@ void CGamePlayerZone::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY int playersInCount = 0; int playersOutCount = 0; - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; CBaseEntity *pPlayer = NULL; - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) + for( int i = 1; i <= gpGlobals->maxClients; i++ ) { pPlayer = UTIL_PlayerByIndex( i ); if ( pPlayer ) @@ -549,40 +549,40 @@ void CGamePlayerZone::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY int hullNumber; hullNumber = human_hull; - if ( pPlayer->pev->flags & FL_DUCKING ) + if( pPlayer->pev->flags & FL_DUCKING ) { hullNumber = head_hull; } UTIL_TraceModel( pPlayer->pev->origin, pPlayer->pev->origin, hullNumber, edict(), &trace ); - if ( trace.fStartSolid ) + if( trace.fStartSolid ) { playersInCount++; - if ( m_iszInTarget ) + if( m_iszInTarget ) { - FireTargets( STRING(m_iszInTarget), pPlayer, pActivator, useType, value ); + FireTargets( STRING( m_iszInTarget ), pPlayer, pActivator, useType, value ); } } else { playersOutCount++; - if ( m_iszOutTarget ) + if( m_iszOutTarget ) { - FireTargets( STRING(m_iszOutTarget), pPlayer, pActivator, useType, value ); + FireTargets( STRING( m_iszOutTarget ), pPlayer, pActivator, useType, value ); } } } } - if ( m_iszInCount ) + if( m_iszInCount ) { - FireTargets( STRING(m_iszInCount), pActivator, this, USE_SET, playersInCount ); + FireTargets( STRING( m_iszInCount ), pActivator, this, USE_SET, playersInCount ); } - if ( m_iszOutCount ) + if( m_iszOutCount ) { - FireTargets( STRING(m_iszOutCount), pActivator, this, USE_SET, playersOutCount ); + FireTargets( STRING( m_iszOutCount ), pActivator, this, USE_SET, playersOutCount ); } } @@ -605,12 +605,12 @@ LINK_ENTITY_TO_CLASS( game_player_hurt, CGamePlayerHurt ) void CGamePlayerHurt::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; - if ( pActivator->IsPlayer() ) + if( pActivator->IsPlayer() ) { - if ( pev->dmg < 0 ) + if( pev->dmg < 0 ) pActivator->TakeHealth( -pev->dmg, DMG_GENERIC ); else pActivator->TakeDamage( pev, pev, pev->dmg, DMG_GENERIC ); @@ -618,7 +618,7 @@ void CGamePlayerHurt::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY SUB_UseTargets( pActivator, useType, value ); - if ( RemoveOnFire() ) + if( RemoveOnFire() ) { UTIL_Remove( this ); } @@ -665,7 +665,7 @@ void CGameCounter::Spawn( void ) void CGameCounter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; switch( useType ) @@ -681,16 +681,16 @@ void CGameCounter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE SetCountValue( (int)value ); break; } - - if ( HitLimit() ) + + if( HitLimit() ) { SUB_UseTargets( pActivator, USE_TOGGLE, 0 ); - if ( RemoveOnFire() ) + if( RemoveOnFire() ) { UTIL_Remove( this ); } - - if ( ResetOnFire() ) + + if( ResetOnFire() ) { ResetCount(); } @@ -716,12 +716,12 @@ LINK_ENTITY_TO_CLASS( game_counter_set, CGameCounterSet ) void CGameCounterSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; SUB_UseTargets( pActivator, USE_SET, pev->frags ); - if ( RemoveOnFire() ) + if( RemoveOnFire() ) { UTIL_Remove( this ); } @@ -756,19 +756,19 @@ void CGamePlayerEquip::KeyValue( KeyValueData *pkvd ) { CRulePointEntity::KeyValue( pkvd ); - if ( !pkvd->fHandled ) + if( !pkvd->fHandled ) { - for ( int i = 0; i < MAX_EQUIP; i++ ) + for( int i = 0; i < MAX_EQUIP; i++ ) { - if ( !m_weaponNames[i] ) + if( !m_weaponNames[i] ) { char tmp[128]; UTIL_StripToken( pkvd->szKeyName, tmp ); - m_weaponNames[i] = ALLOC_STRING(tmp); - m_weaponCount[i] = atoi(pkvd->szValue); - m_weaponCount[i] = max(1,m_weaponCount[i]); + m_weaponNames[i] = ALLOC_STRING( tmp ); + m_weaponCount[i] = atoi( pkvd->szValue ); + m_weaponCount[i] = max( 1, m_weaponCount[i] ); pkvd->fHandled = TRUE; break; } @@ -778,10 +778,10 @@ void CGamePlayerEquip::KeyValue( KeyValueData *pkvd ) void CGamePlayerEquip::Touch( CBaseEntity *pOther ) { - if ( !CanFireForActivator( pOther ) ) + if( !CanFireForActivator( pOther ) ) return; - if ( UseOnly() ) + if( UseOnly() ) return; EquipPlayer( pOther ); @@ -791,21 +791,21 @@ void CGamePlayerEquip::EquipPlayer( CBaseEntity *pEntity ) { CBasePlayer *pPlayer = NULL; - if ( pEntity->IsPlayer() ) + if( pEntity->IsPlayer() ) { pPlayer = (CBasePlayer *)pEntity; } - if ( !pPlayer ) + if( !pPlayer ) return; - for ( int i = 0; i < MAX_EQUIP; i++ ) + for( int i = 0; i < MAX_EQUIP; i++ ) { - if ( !m_weaponNames[i] ) + if( !m_weaponNames[i] ) break; - for ( int j = 0; j < m_weaponCount[i]; j++ ) + for( int j = 0; j < m_weaponCount[i]; j++ ) { - pPlayer->GiveNamedItem( STRING(m_weaponNames[i]) ); + pPlayer->GiveNamedItem( STRING( m_weaponNames[i] ) ); } } } @@ -844,9 +844,9 @@ const char *CGamePlayerTeam::TargetTeamName( const char *pszTargetName ) { CBaseEntity *pTeamEntity = NULL; - while ((pTeamEntity = UTIL_FindEntityByTargetname( pTeamEntity, pszTargetName )) != NULL) + while( ( pTeamEntity = UTIL_FindEntityByTargetname( pTeamEntity, pszTargetName ) ) != NULL ) { - if ( FClassnameIs( pTeamEntity->pev, "game_team_master" ) ) + if( FClassnameIs( pTeamEntity->pev, "game_team_master" ) ) return pTeamEntity->TeamID(); } @@ -855,10 +855,10 @@ const char *CGamePlayerTeam::TargetTeamName( const char *pszTargetName ) void CGamePlayerTeam::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !CanFireForActivator( pActivator ) ) + if( !CanFireForActivator( pActivator ) ) return; - if ( pActivator->IsPlayer() ) + if( pActivator->IsPlayer() ) { const char *pszTargetTeam = TargetTeamName( STRING(pev->target) ); if ( pszTargetTeam ) @@ -868,7 +868,7 @@ void CGamePlayerTeam::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY } } - if ( RemoveOnFire() ) + if( RemoveOnFire() ) { UTIL_Remove( this ); } diff --git a/dlls/plats.cpp b/dlls/plats.cpp index 00b05bec..3034fd93 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -104,111 +104,100 @@ void CBasePlatTrain::KeyValue( KeyValueData *pkvd ) void CBasePlatTrain::Precache( void ) { + const char *pszSound; + BOOL NullSound = FALSE; + // set the plat's "in-motion" sound switch( m_bMoveSnd ) { - case 0: - pev->noiseMoving = MAKE_STRING( "common/null.wav" ); - break; case 1: - PRECACHE_SOUND( "plats/bigmove1.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/bigmove1.wav" ); + pszSound = "plats/bigmove1.wav"; break; case 2: - PRECACHE_SOUND( "plats/bigmove2.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/bigmove2.wav" ); + pszSound = "plats/bigmove2.wav"; break; case 3: - PRECACHE_SOUND( "plats/elevmove1.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/elevmove1.wav" ); + pszSound = "plats/elevmove1.wav"; break; case 4: - PRECACHE_SOUND( "plats/elevmove2.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/elevmove2.wav" ); + pszSound = "plats/elevmove2.wav"; break; case 5: - PRECACHE_SOUND( "plats/elevmove3.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/elevmove3.wav" ); + pszSound = "plats/elevmove3.wav"; break; case 6: - PRECACHE_SOUND( "plats/freightmove1.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/freightmove1.wav" ); + pszSound = "plats/freightmove1.wav"; break; case 7: - PRECACHE_SOUND( "plats/freightmove2.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/freightmove2.wav" ); + pszSound = "plats/freightmove2.wav"; break; case 8: - PRECACHE_SOUND( "plats/heavymove1.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/heavymove1.wav" ); + pszSound = "plats/heavymove1.wav"; break; case 9: - PRECACHE_SOUND( "plats/rackmove1.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/rackmove1.wav" ); + pszSound = "plats/rackmove1.wav"; break; case 10: - PRECACHE_SOUND( "plats/railmove1.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/railmove1.wav" ); + pszSound = "plats/railmove1.wav"; break; case 11: - PRECACHE_SOUND( "plats/squeekmove1.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/squeekmove1.wav" ); + pszSound = "plats/squeekmove1.wav"; break; case 12: - PRECACHE_SOUND( "plats/talkmove1.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/talkmove1.wav" ); + pszSound = "plats/talkmove1.wav"; break; case 13: - PRECACHE_SOUND( "plats/talkmove2.wav" ); - pev->noiseMoving = MAKE_STRING( "plats/talkmove2.wav" ); + pszSound = "plats/talkmove2.wav"; break; + case 0: default: - pev->noiseMoving = MAKE_STRING( "common/null.wav" ); + pszSound = "common/null.wav"; + NullSound = TRUE; break; } + if( !NullSound ) + PRECACHE_SOUND( pszSound ); + pev->noiseMoving = MAKE_STRING( pszSound ); + NullSound = FALSE; + // set the plat's 'reached destination' stop sound switch( m_bStopSnd ) { - case 0: - pev->noiseArrived = MAKE_STRING( "common/null.wav" ); - break; case 1: - PRECACHE_SOUND( "plats/bigstop1.wav" ); - pev->noiseArrived = MAKE_STRING( "plats/bigstop1.wav" ); + pszSound = "plats/bigstop1.wav"; break; case 2: - PRECACHE_SOUND( "plats/bigstop2.wav" ); - pev->noiseArrived = MAKE_STRING( "plats/bigstop2.wav" ); + pszSound = "plats/bigstop2.wav"; break; case 3: - PRECACHE_SOUND( "plats/freightstop1.wav" ); - pev->noiseArrived = MAKE_STRING( "plats/freightstop1.wav" ); + pszSound = "plats/freightstop1.wav"; break; case 4: - PRECACHE_SOUND( "plats/heavystop2.wav" ); - pev->noiseArrived = MAKE_STRING( "plats/heavystop2.wav" ); + pszSound = "plats/heavystop2.wav"; break; case 5: - PRECACHE_SOUND( "plats/rackstop1.wav" ); - pev->noiseArrived = MAKE_STRING( "plats/rackstop1.wav" ); + pszSound = "plats/rackstop1.wav"; break; case 6: - PRECACHE_SOUND( "plats/railstop1.wav" ); - pev->noiseArrived = MAKE_STRING( "plats/railstop1.wav" ); + pszSound = "plats/railstop1.wav"; break; case 7: - PRECACHE_SOUND( "plats/squeekstop1.wav" ); - pev->noiseArrived = MAKE_STRING( "plats/squeekstop1.wav" ); + pszSound = "plats/squeekstop1.wav"; break; case 8: - PRECACHE_SOUND( "plats/talkstop1.wav" ); - pev->noiseArrived = MAKE_STRING( "plats/talkstop1.wav" ); + pszSound = "plats/talkstop1.wav"; break; + case 0: default: - pev->noiseArrived = MAKE_STRING( "common/null.wav" ); + pszSound = "common/null.wav"; + NullSound = TRUE; break; } + + if( !NullSound ) + PRECACHE_SOUND( pszSound ); + pev->noiseArrived = MAKE_STRING( pszSound ); } // @@ -1482,6 +1471,8 @@ void CFuncTrackTrain::Spawn( void ) void CFuncTrackTrain::Precache( void ) { + const char *pszSound; + if( m_flVolume == 0.0 ) m_flVolume = 1.0; @@ -1489,34 +1480,36 @@ void CFuncTrackTrain::Precache( void ) { default: // no sound - pev->noise = 0; + pszSound = NULL; break; case 1: - PRECACHE_SOUND( "plats/ttrain1.wav" ); - pev->noise = MAKE_STRING("plats/ttrain1.wav" ); + pszSound = "plats/ttrain1.wav"; break; case 2: - PRECACHE_SOUND( "plats/ttrain2.wav" ); - pev->noise = MAKE_STRING( "plats/ttrain2.wav" ); + pszSound = "plats/ttrain2.wav"; break; case 3: - PRECACHE_SOUND( "plats/ttrain3.wav" ); - pev->noise = MAKE_STRING( "plats/ttrain3.wav" ); + pszSound = "plats/ttrain3.wav"; break; case 4: - PRECACHE_SOUND( "plats/ttrain4.wav" ); - pev->noise = MAKE_STRING( "plats/ttrain4.wav" ); + pszSound = "plats/ttrain4.wav"; break; case 5: - PRECACHE_SOUND( "plats/ttrain6.wav" ); - pev->noise = MAKE_STRING( "plats/ttrain6.wav" ); + pszSound = "plats/ttrain6.wav"; break; case 6: - PRECACHE_SOUND( "plats/ttrain7.wav" ); - pev->noise = MAKE_STRING( "plats/ttrain7.wav" ); + pszSound = "plats/ttrain7.wav"; break; } + if( !pszSound ) + { + PRECACHE_SOUND( pszSound ); + pev->noise = MAKE_STRING( pszSound ); + } + else + pev->noise = 0; + PRECACHE_SOUND( "plats/ttrain_brake1.wav" ); PRECACHE_SOUND( "plats/ttrain_start1.wav" ); diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index 2959d96d..57d8d031 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -1689,7 +1689,7 @@ void NextLevel( void ) // go back to start if no trigger_changelevel if( FNullEnt( pent ) ) { - gpGlobals->mapname = ALLOC_STRING( "start" ); + gpGlobals->mapname = MAKE_STRING( "start" ); pChange = GetClassPtr( (CChangeLevel *)NULL ); strcpy( pChange->m_szMapName, "start" ); } From 14e75025bb64f730fa42081fa594c397ca064b2d Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 20 Jul 2017 10:33:39 +0500 Subject: [PATCH 092/211] Show long nicknames in scoreboard. Show fulli nicknames in scoreboard. --- cl_dll/scoreboard.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index b20e316c..3adbaab6 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -92,7 +92,7 @@ We have a minimum width of 1-320 - we could have the field widths scale with it? // X positions // relative to the side of the scoreboard -#define NAME_RANGE_MIN 20 +#define NAME_RANGE_MIN -100 #define NAME_RANGE_MAX 145 #define KILLS_RANGE_MIN 130 #define KILLS_RANGE_MAX 170 @@ -145,7 +145,7 @@ int CHudScoreboard::Draw( float fTime ) int xpos = NAME_RANGE_MIN + xpos_rel; FAR_RIGHT = can_show_packetloss ? PL_RANGE_MAX : PING_RANGE_MAX; - FAR_RIGHT += 5; + FAR_RIGHT += 125; if( cl_scoreboard_bg && cl_scoreboard_bg->value ) gHUD.DrawDarkRectangle( xpos - 5, ypos - 5, FAR_RIGHT, ROW_RANGE_MAX ); if( !gHUD.m_Teamplay ) @@ -340,7 +340,7 @@ int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, } FAR_RIGHT = can_show_packetloss ? PL_RANGE_MAX : PING_RANGE_MAX; - FAR_RIGHT += 5; + FAR_RIGHT += 125; // draw the players, in order, and restricted to team if set while( 1 ) From 7a5c29cbc9f68bf1fbfe1a454ae351721155b640 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 20 Jul 2017 10:51:34 +0500 Subject: [PATCH 093/211] Clear any effects on disconnect. --- dlls/client.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/client.cpp b/dlls/client.cpp index 480a9506..3e23821f 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -125,6 +125,7 @@ void ClientDisconnect( edict_t *pEntity ) // since the edict doesn't get deleted, fix it so it doesn't interfere. pEntity->v.takedamage = DAMAGE_NO;// don't attract autoaim pEntity->v.solid = SOLID_NOT;// nonsolid + pEntity->v.effects = 0;// clear any effects UTIL_SetOrigin( &pEntity->v, pEntity->v.origin ); g_pGameRules->ClientDisconnected( pEntity ); From ea8f2bed7715b48bdf012b1c6bcbcf8881e5400a Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 20 Jul 2017 12:13:04 +0500 Subject: [PATCH 094/211] Implement cl_viewbob cvar for viewmodel bobbing. Same as in http://am.half-lifecreations.com/forums/index.php?topic=288.0 --- cl_dll/hud.cpp | 2 ++ cl_dll/view.cpp | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 0f3b45bc..05bda284 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -35,6 +35,7 @@ extern client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, extern cvar_t *sensitivity; cvar_t *cl_lw = NULL; +cvar_t *cl_viewbob = NULL; void ShutdownInput( void ); @@ -194,6 +195,7 @@ void CHud::Init( void ) m_pCvarStealMouse = CVAR_CREATE( "hud_capturemouse", "1", FCVAR_ARCHIVE ); m_pCvarDraw = CVAR_CREATE( "hud_draw", "1", FCVAR_ARCHIVE ); cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); + cl_viewbob = CVAR_CREATE( "cl_viewbob", "0", FCVAR_ARCHIVE ); m_pSpriteList = NULL; diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index dcd2b1af..efa4b104 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -78,6 +78,7 @@ extern cvar_t *cl_forwardspeed; extern cvar_t *chase_active; extern cvar_t *scr_ofsx, *scr_ofsy, *scr_ofsz; extern cvar_t *cl_vsmoothing; +extern cvar_t *cl_viewbob; extern Vector dead_viewangles; #define CAM_MODE_RELAX 1 @@ -527,7 +528,7 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams ) V_AddIdle( pparams ); // offsets - if ( pparams->health <= 0 ) + if( pparams->health <= 0 ) { VectorCopy( dead_viewangles, angles ); } @@ -598,6 +599,9 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams ) view->angles[ROLL] -= bob * 1; view->angles[PITCH] -= bob * 0.3; + if( cl_viewbob && cl_viewbob->value ) + VectorCopy( view->angles, view->curstate.angles ); + // pushing the view origin down off of the same X/Z plane as the ent's origin will give the // gun a very nice 'shifting' effect when the player looks up/down. If there is a problem // with view model distortion, this may be a cause. (SJB). From c9ac2c6dabf511a5b68526876d47a8579c2bf02c Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 20 Jul 2017 12:22:02 +0500 Subject: [PATCH 095/211] Implement mp_satchelfix cvar. --- dlls/doors.cpp | 10 +++++++--- dlls/game.cpp | 2 ++ dlls/game.h | 1 + dlls/player.cpp | 4 +++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/dlls/doors.cpp b/dlls/doors.cpp index ce901ee8..61a04ed2 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -22,6 +22,7 @@ #include "util.h" #include "cbase.h" #include "doors.h" +#include "game.h" #include "weapons.h" extern void SetMovedir( entvars_t *ev ); @@ -737,9 +738,12 @@ void CBaseDoor::Blocked( CBaseEntity *pOther ) if( pev->dmg ) pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH ); - // Detonate satchels - if( !strcmp( "monster_satchel", STRING( pOther->pev->classname ) ) ) - ( (CSatchel*)pOther )->Use( this, this, USE_ON, 0 ); + if( satchelfix.value ) + { + // Detonate satchels + if( !strcmp( "monster_satchel", STRING( pOther->pev->classname ) ) ) + ( (CSatchel*)pOther )->Use( this, this, USE_ON, 0 ); + } // if a door has a negative wait, it would never come back if blocked, // so let it just squash the object to death real fast diff --git a/dlls/game.cpp b/dlls/game.cpp index b109f376..4354a63d 100644 --- a/dlls/game.cpp +++ b/dlls/game.cpp @@ -31,6 +31,7 @@ cvar_t friendlyfire = { "mp_friendlyfire","0", FCVAR_SERVER }; cvar_t falldamage = { "mp_falldamage","0", FCVAR_SERVER }; cvar_t weaponstay = { "mp_weaponstay","0", FCVAR_SERVER }; cvar_t selfgauss = { "mp_selfgauss", "1", FCVAR_SERVER }; +cvar_t satchelfix = { "mp_satchelfix", "0", FCVAR_SERVER }; cvar_t forcerespawn = { "mp_forcerespawn","1", FCVAR_SERVER }; cvar_t flashlight = { "mp_flashlight","0", FCVAR_SERVER }; cvar_t aimcrosshair = { "mp_autocrosshair","1", FCVAR_SERVER }; @@ -469,6 +470,7 @@ void GameDLLInit( void ) CVAR_REGISTER( &falldamage ); CVAR_REGISTER( &weaponstay ); CVAR_REGISTER( &selfgauss ); + CVAR_REGISTER( &satchelfix ); CVAR_REGISTER( &forcerespawn ); CVAR_REGISTER( &flashlight ); CVAR_REGISTER( &aimcrosshair ); diff --git a/dlls/game.h b/dlls/game.h index e29b2563..a6d0cd1c 100644 --- a/dlls/game.h +++ b/dlls/game.h @@ -28,6 +28,7 @@ extern cvar_t friendlyfire; extern cvar_t falldamage; extern cvar_t weaponstay; extern cvar_t selfgauss; +extern cvar_t satchelfix; extern cvar_t forcerespawn; extern cvar_t flashlight; extern cvar_t aimcrosshair; diff --git a/dlls/player.cpp b/dlls/player.cpp index 0d86caf8..1a7bc206 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -823,7 +823,9 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit ) for( i = 0; i < MAX_AMMO_SLOTS; i++ ) m_rgAmmo[i] = 0; - DeactivateSatchels( this ); + if( satchelfix.value ) + DeactivateSatchels( this ); + UpdateClientData(); // send Selected Weapon Message to our client From d1fbb99574d66c35de21a3b3b45a7c137b33f6e0 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 20 Jul 2017 23:32:06 +0500 Subject: [PATCH 096/211] Fix some warnings yet. --- cl_dll/cl_util.h | 2 +- cl_dll/hud_spectator.cpp | 10 +++---- cl_dll/hud_spectator.h | 4 +-- dlls/client.cpp | 4 +-- dlls/doors.cpp | 2 +- dlls/multiplay_gamerules.cpp | 2 +- dlls/nihilanth.cpp | 20 +++++++------- engine/cdll_int.h | 52 ++++++++++++++++++------------------ 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/cl_dll/cl_util.h b/cl_dll/cl_util.h index 22555caa..1996543d 100644 --- a/cl_dll/cl_util.h +++ b/cl_dll/cl_util.h @@ -144,7 +144,7 @@ inline void CenterPrint( const char *string ) #define GetPlayerInfo ( *gEngfuncs.pfnGetPlayerInfo ) // sound functions -inline void PlaySound( char *szSound, float vol ) { gEngfuncs.pfnPlaySoundByName( szSound, vol ); } +inline void PlaySound( const char *szSound, float vol ) { gEngfuncs.pfnPlaySoundByName( szSound, vol ); } inline void PlaySound( int iSound, float vol ) { gEngfuncs.pfnPlaySoundByIndex( iSound, vol ); } #define max(a, b) (((a) > (b)) ? (a) : (b)) diff --git a/cl_dll/hud_spectator.cpp b/cl_dll/hud_spectator.cpp index ff6eb8ff..5ffce74a 100644 --- a/cl_dll/hud_spectator.cpp +++ b/cl_dll/hud_spectator.cpp @@ -175,13 +175,13 @@ void UTIL_StringToVector( float * pVector, const char *pString ) } } -int UTIL_FindEntityInMap( char * name, float * origin, float * angle ) +int UTIL_FindEntityInMap( const char *name, float *origin, float *angle ) { int n, found = 0; char keyname[256]; char token[2048]; - cl_entity_t * pEnt = gEngfuncs.GetEntityByIndex( 0 ); // get world model + cl_entity_t *pEnt = gEngfuncs.GetEntityByIndex( 0 ); // get world model if( !pEnt ) return 0; @@ -189,7 +189,7 @@ int UTIL_FindEntityInMap( char * name, float * origin, float * angle ) if( !pEnt->model ) return 0; - char * data = pEnt->model->entities; + char *data = pEnt->model->entities; while( data ) { @@ -1374,12 +1374,12 @@ void CHudSpectator::DeathMessage( int victim ) AddOverviewEntityToList(m_hsprPlayerDead, pl, gEngfuncs.GetClientTime() + 2.0f ); } -bool CHudSpectator::AddOverviewEntityToList(HSPRITE sprite, cl_entity_t *ent, double killTime) +bool CHudSpectator::AddOverviewEntityToList( HSPRITE sprite, cl_entity_t *ent, double killTime ) { for( int i = 0; i < MAX_OVERVIEW_ENTITIES; i++ ) { // find empty entity slot - if( m_OverviewEntities[i].entity == NULL) + if( m_OverviewEntities[i].entity == NULL ) { m_OverviewEntities[i].entity = ent; m_OverviewEntities[i].hSprite = sprite; diff --git a/cl_dll/hud_spectator.h b/cl_dll/hud_spectator.h index f60353db..58026668 100644 --- a/cl_dll/hud_spectator.h +++ b/cl_dll/hud_spectator.h @@ -64,11 +64,11 @@ public: void CheckOverviewEntities(); void DrawOverview(); void DrawOverviewEntities(); - void GetMapPosition( float * returnvec ); + void GetMapPosition( float *returnvec ); void DrawOverviewLayer(); void LoadMapSprites(); bool ParseOverviewFile(); - bool IsActivePlayer( cl_entity_t * ent ); + bool IsActivePlayer( cl_entity_t *ent ); void SetModes( int iMainMode, int iInsetMode ); void HandleButtonsDown( int ButtonPressed ); void HandleButtonsUp( int ButtonPressed ); diff --git a/dlls/client.cpp b/dlls/client.cpp index 3e23821f..569b1a53 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -566,7 +566,7 @@ void ClientCommand( edict_t *pEntity ) // notify other clients of player switching to spectator mode UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s switched to spectator mode\n", - ( pev->netname && STRING(pev->netname)[0] != 0 ) ? STRING(pev->netname) : "unconnected" ) ); + ( pev->netname && ( STRING( pev->netname ) )[0] != 0 ) ? STRING( pev->netname ) : "unconnected" ) ); } else ClientPrint( pev, HUD_PRINTCONSOLE, "Spectator mode is disabled.\n" ); @@ -629,7 +629,7 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) return; // msg everyone if someone changes their name, and it isn't the first time (changing no name to current name) - if( pEntity->v.netname && STRING( pEntity->v.netname )[0] != 0 && !FStrEq( STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ) ) + if( pEntity->v.netname && ( STRING( pEntity->v.netname ) )[0] != 0 && !FStrEq( STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ) ) { char sName[256]; char *pName = g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ); diff --git a/dlls/doors.cpp b/dlls/doors.cpp index 61a04ed2..90678df6 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -397,7 +397,7 @@ void CBaseDoor::Precache( void ) pszSound = "doors/doorstop5.wav"; break; case 6: - pszSound = "doors/doorstop6.wav" + pszSound = "doors/doorstop6.wav"; break; case 7: pszSound = "doors/doorstop7.wav"; diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 494ac4f6..a898158f 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -423,7 +423,7 @@ void CHalfLifeMultiplay::InitHUD( CBasePlayer *pl ) { // notify other clients of player joining the game UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s has joined the game\n", - ( pl->pev->netname && STRING( pl->pev->netname )[0] != 0 ) ? STRING( pl->pev->netname ) : "unconnected" ) ); + ( pl->pev->netname && ( STRING( pl->pev->netname ) )[0] != 0 ) ? STRING( pl->pev->netname ) : "unconnected" ) ); // team match? if( g_teamplay ) diff --git a/dlls/nihilanth.cpp b/dlls/nihilanth.cpp index 1f9b0f88..34375a58 100644 --- a/dlls/nihilanth.cpp +++ b/dlls/nihilanth.cpp @@ -642,14 +642,14 @@ void CNihilanth::MakeFriend( Vector vecStart ) for( i = 0; i < 3; i++ ) { - if( m_hFriend[i] != NULL && !m_hFriend[i]->IsAlive() ) + if( m_hFriend[i] != 0 && !m_hFriend[i]->IsAlive() ) { if( pev->rendermode == kRenderNormal ) // don't do it if they are already fading m_hFriend[i]->MyMonsterPointer()->FadeMonster(); m_hFriend[i] = NULL; } - if( m_hFriend[i] == NULL ) + if( m_hFriend[i] == 0 ) { if( RANDOM_LONG( 0, 1 ) == 0 ) { @@ -675,7 +675,7 @@ void CNihilanth::MakeFriend( Vector vecStart ) m_hFriend[i] = Create( "monster_alien_slave", node.m_vecOrigin, pev->angles ); } } - if( m_hFriend[i] != NULL ) + if( m_hFriend[i] != 0 ) { EMIT_SOUND( m_hFriend[i]->edict(), CHAN_WEAPON, "debris/beamstart7.wav", 1.0, ATTN_NORM ); } @@ -722,7 +722,7 @@ void CNihilanth::NextActivity() } } - if( ( pev->health < gSkillData.nihilanthHealth / 2 || m_iActiveSpheres < N_SPHERES / 2 ) && m_hRecharger == NULL && m_iLevel <= 9 ) + if( ( pev->health < gSkillData.nihilanthHealth / 2 || m_iActiveSpheres < N_SPHERES / 2 ) && m_hRecharger == 0 && m_iLevel <= 9 ) { char szName[64]; @@ -881,7 +881,7 @@ void CNihilanth::HuntThink( void ) } // look for current enemy - if( m_hEnemy != 0 && m_hRecharger == NULL ) + if( m_hEnemy != 0 && m_hRecharger == 0 ) { if( FVisible( m_hEnemy ) ) { @@ -1057,7 +1057,7 @@ void CNihilanth::HandleAnimEvent( MonsterEvent_t *pEvent ) break; case 2: // zen - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { if( RANDOM_LONG( 0, 4 ) == 0 ) EMIT_SOUND( edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pAttackSounds ), 1.0, 0.2 ); @@ -1098,7 +1098,7 @@ void CNihilanth::HandleAnimEvent( MonsterEvent_t *pEvent ) break; case 3: // prayer - if (m_hEnemy != NULL) + if( m_hEnemy != 0 ) { char szText[32]; @@ -1178,7 +1178,7 @@ void CNihilanth::HandleAnimEvent( MonsterEvent_t *pEvent ) } break; case 6: - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { Vector vecSrc, vecAngles; GetAttachment( 2, vecSrc, vecAngles ); @@ -1208,7 +1208,7 @@ void CNihilanth::CommandUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_ CBaseEntity *pTouch = UTIL_FindEntityByTargetname( NULL, m_szDeadTouch ); if( pTouch ) { - if( m_hEnemy != NULL ) + if( m_hEnemy != 0 ) { pTouch->Touch( m_hEnemy ); } @@ -1597,7 +1597,7 @@ void CNihilanthHVR::TeleportThink( void ) if( m_hTargetEnt != 0 ) m_hTargetEnt->Use( m_hEnemy, m_hEnemy, USE_ON, 1.0 ); - if( m_hTouch != 0 && m_hEnemy != NULL ) + if( m_hTouch != 0 && m_hEnemy != 0 ) m_hTouch->Touch( m_hEnemy ); } else diff --git a/engine/cdll_int.h b/engine/cdll_int.h index 056146b4..d45bb9d5 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -128,7 +128,7 @@ typedef struct cl_enginefuncs_s void (*pfnSPR_DrawAdditive)( int frame, int x, int y, const wrect_t *prc ); void (*pfnSPR_EnableScissor)( int x, int y, int width, int height ); void (*pfnSPR_DisableScissor)( void ); - client_sprite_t *(*pfnSPR_GetList)( char *psz, int *piCount ); + client_sprite_t *(*pfnSPR_GetList)( const char *psz, int *piCount ); // screen handlers void (*pfnFillRGBA)( int x, int y, int width, int height, int r, int g, int b, int a ); @@ -136,20 +136,20 @@ typedef struct cl_enginefuncs_s void (*pfnSetCrosshair)( HSPRITE hspr, wrect_t rc, int r, int g, int b ); // cvar handlers - struct cvar_s *(*pfnRegisterVariable)( char *szName, char *szValue, int flags ); - float (*pfnGetCvarFloat)( char *szName ); - char* (*pfnGetCvarString)( char *szName ); + struct cvar_s *(*pfnRegisterVariable)( const char *szName, const char *szValue, int flags ); + float (*pfnGetCvarFloat)( const char *szName ); + char* (*pfnGetCvarString)( const char *szName ); // command handlers - int (*pfnAddCommand)( char *cmd_name, void (*function)(void) ); - int (*pfnHookUserMsg)( char *szMsgName, pfnUserMsgHook pfn ); - int (*pfnServerCmd)( char *szCmdString ); - int (*pfnClientCmd)( char *szCmdString ); + int (*pfnAddCommand)( const char *cmd_name, void (*function)(void) ); + int (*pfnHookUserMsg)( const char *szMsgName, pfnUserMsgHook pfn ); + int (*pfnServerCmd)( const char *szCmdString ); + int (*pfnClientCmd)( const char *szCmdString ); void (*pfnGetPlayerInfo)( int ent_num, hud_player_info_t *pinfo ); // sound handlers - void (*pfnPlaySoundByName)( char *szSound, float volume ); + void (*pfnPlaySoundByName)( const char *szSound, float volume ); void (*pfnPlaySoundByIndex)( int iSound, float volume ); // vector helpers @@ -158,7 +158,7 @@ typedef struct cl_enginefuncs_s // text message system client_textmessage_t *(*pfnTextMessageGet)( const char *pName ); int (*pfnDrawCharacter)( int x, int y, int number, int r, int g, int b ); - int (*pfnDrawConsoleString)( int x, int y, char *string ); + int (*pfnDrawConsoleString)( int x, int y, const char *string ); void (*pfnDrawSetTextColor)( float r, float g, float b ); void (*pfnDrawConsoleStringLen)( const char *string, int *length, int *height ); @@ -171,19 +171,19 @@ typedef struct cl_enginefuncs_s void (*GetViewAngles)( float * ); void (*SetViewAngles)( float * ); int (*GetMaxClients)( void ); - void (*Cvar_SetValue)( char *cvar, float value ); + void (*Cvar_SetValue)( const char *cvar, float value ); int (*Cmd_Argc)( void ); char *(*Cmd_Argv)( int arg ); - void (*Con_Printf)( char *fmt, ... ); - void (*Con_DPrintf)( char *fmt, ... ); - void (*Con_NPrintf)( int pos, char *fmt, ... ); - void (*Con_NXPrintf)( struct con_nprint_s *info, char *fmt, ... ); + void (*Con_Printf)( const char *fmt, ... ); + void (*Con_DPrintf)( const char *fmt, ... ); + void (*Con_NPrintf)( int pos, const char *fmt, ... ); + void (*Con_NXPrintf)( struct con_nprint_s *info, const char *fmt, ... ); const char* (*PhysInfo_ValueForKey)( const char *key ); const char* (*ServerInfo_ValueForKey)( const char *key ); float (*GetClientMaxspeed)( void ); - int (*CheckParm)( char *parm, char **ppnext ); + int (*CheckParm)( const char *parm, const char **ppnext ); void (*Key_Event)( int key, int down ); void (*GetMousePosition)( int *mx, int *my ); @@ -212,7 +212,7 @@ typedef struct cl_enginefuncs_s void (*pfnWeaponAnim)( int iAnim, int body ); float (*pfnRandomFloat)( float flLow, float flHigh ); int (*pfnRandomLong)( int lLow, int lHigh ); - void (*pfnHookEvent)( char *name, void ( *pfnEvent )( struct event_args_s *args )); + void (*pfnHookEvent)( const char *name, void ( *pfnEvent )( struct event_args_s *args )); int (*Con_IsVisible) (); const char *(*pfnGetGameDirectory)( void ); struct cvar_s *(*pfnGetCvarPointer)( const char *szName ); @@ -223,8 +223,8 @@ typedef struct cl_enginefuncs_s void* (*VGui_GetPanel)( ); void (*VGui_ViewportPaintBackground)( int extents[4] ); - byte* (*COM_LoadFile)( char *path, int usehunk, int *pLength ); - char* (*COM_ParseFile)( char *data, char *token ); + byte* (*COM_LoadFile)( const char *path, int usehunk, int *pLength ); + char* (*COM_ParseFile)( const char *data, const char *token ); void (*COM_FreeFile)( void *buffer ); struct triangleapi_s *pTriAPI; @@ -252,7 +252,7 @@ typedef struct cl_enginefuncs_s // Gets a unique ID for the specified player. This is the same even if you see the player on a different server. // iPlayer is an entity index, so client 0 would use iPlayer=1. // Returns false if there is no player on the server in the specified slot. - qboolean (*GetPlayerUniqueID)(int iPlayer, char playerID[16]); + qboolean (*GetPlayerUniqueID)(int iPlayer, const char playerID[16]); // TrackerID access int (*GetTrackerIDForPlayer)(int playerSlot); @@ -260,7 +260,7 @@ typedef struct cl_enginefuncs_s // Same as pfnServerCmd, but the message goes in the unreliable stream so it can't clog the net stream // (but it might not get there). - int ( *pfnServerCmdUnreliable )( char *szCmdString ); + int ( *pfnServerCmdUnreliable )( const char *szCmdString ); void (*pfnGetMousePos)( struct tagPOINT *ppt ); void (*pfnSetMousePos)( int x, int y ); @@ -285,12 +285,12 @@ typedef struct cl_enginefuncs_s const char *(*LocalPlayerInfo_ValueForKey)( const char* key ); int (*pfnVGUI2DrawCharacter)( int x, int y, int ch, unsigned int font ); int (*pfnVGUI2DrawCharacterAdditive)( int x, int y, int ch, int r, int g, int b, unsigned int font ); - unsigned int (*pfnGetApproxWavePlayLen)( char *filename ); + unsigned int (*pfnGetApproxWavePlayLen)( const char *filename ); void* (*GetCareerGameUI)( void ); // g-cont. !!!! potential crash-point! - void (*Cvar_Set)( char *name, char *value ); + void (*Cvar_Set)( const char *name, const char *value ); int (*pfnIsPlayingCareerMatch)( void ); - void (*pfnPlaySoundVoiceByName)( char *szSound, float volume, int pitch ); - void (*pfnPrimeMusicStream)( char *filename, int looping ); + void (*pfnPlaySoundVoiceByName)( const char *szSound, float volume, int pitch ); + void (*pfnPrimeMusicStream)( const char *filename, int looping ); double (*pfnSys_FloatTime)( void ); // decay funcs @@ -298,7 +298,7 @@ typedef struct cl_enginefuncs_s void (*pfnConstructTutorMessageDecayBuffer)( int *buffer, int buflen ); void (*pfnResetTutorMessageDecayData)( void ); - void (*pfnPlaySoundByNameAtPitch)( char *szSound, float volume, int pitch ); + void (*pfnPlaySoundByNameAtPitch)( const char *szSound, float volume, int pitch ); void (*pfnFillRGBABlend)( int x, int y, int width, int height, int r, int g, int b, int a ); int (*pfnGetAppID)( void ); cmdalias_t *(*pfnGetAliases)( void ); From 58a5ca48be81a8d12995d4bd71f4ad9fee274ba7 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 20 Jul 2017 23:42:00 +0500 Subject: [PATCH 097/211] Add protection for vec3_t definition. --- common/mathlib.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/mathlib.h b/common/mathlib.h index fadb97fb..12fb972f 100644 --- a/common/mathlib.h +++ b/common/mathlib.h @@ -18,7 +18,12 @@ typedef float vec_t; typedef vec_t vec2_t[2]; + +#ifndef DID_VEC3_T_DEFINE +#define DID_VEC3_T_DEFINE typedef vec_t vec3_t[3]; +#endif + typedef vec_t vec4_t[4]; // x,y,z,w #ifndef M_PI From 3dc0939b40960f1a3e0c7ff9d68849e2dff0ccd7 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Fri, 21 Jul 2017 00:00:38 +0500 Subject: [PATCH 098/211] Prevent buffer overflow. --- cl_dll/text_message.cpp | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/cl_dll/text_message.cpp b/cl_dll/text_message.cpp index 9452cebb..b959fc87 100644 --- a/cl_dll/text_message.cpp +++ b/cl_dll/text_message.cpp @@ -162,42 +162,39 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf int msg_dest = READ_BYTE(); - static char szBuf[6][128]; - const char *msg_text = LookupString( READ_STRING(), &msg_dest ); - msg_text = strcpy( szBuf[0], msg_text ); +#define MSG_BUF_SIZE 128 + char szBuf[6][MSG_BUF_SIZE]; + + strncpy( szBuf[0], LookupString( READ_STRING(), &msg_dest ), MSG_BUF_SIZE - 1 ); + szBuf[0][MSG_BUF_SIZE - 1] = '\0'; + + for( int i = 1; i <= 4; i++ ) + { + // keep reading strings and using C format strings for subsituting the strings into the localised text string + strncpy( szBuf[i], LookupString( READ_STRING() ), MSG_BUF_SIZE - 1 ); + szBuf[i][MSG_BUF_SIZE - 1] = '\0'; + StripEndNewlineFromString( szBuf[i] ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines + } - // keep reading strings and using C format strings for subsituting the strings into the localised text string - const char *sstr1 = LookupString( READ_STRING() ); - sstr1 = strcpy( szBuf[1], sstr1 ); - StripEndNewlineFromString( (char*)sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines - const char *sstr2 = LookupString( READ_STRING() ); - sstr2 = strcpy( szBuf[2], sstr2 ); - StripEndNewlineFromString( (char*)sstr2 ); - const char *sstr3 = LookupString( READ_STRING() ); - sstr3 = strcpy( szBuf[3], sstr3 ); - StripEndNewlineFromString( (char*)sstr3 ); - const char *sstr4 = LookupString( READ_STRING() ); - sstr4 = strcpy( szBuf[4], sstr4 ); - StripEndNewlineFromString( (char*)sstr4 ); char *psz = szBuf[5]; switch( msg_dest ) { case HUD_PRINTCENTER: - sprintf( psz, msg_text, sstr1, sstr2, sstr3, sstr4 ); + snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); CenterPrint( ConvertCRtoNL( psz ) ); break; case HUD_PRINTNOTIFY: psz[0] = 1; // mark this message to go into the notify buffer - sprintf( psz + 1, msg_text, sstr1, sstr2, sstr3, sstr4 ); + snprintf( psz + 1, MSG_BUF_SIZE - 1, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); ConsolePrint( ConvertCRtoNL( psz ) ); break; case HUD_PRINTTALK: - sprintf( psz, msg_text, sstr1, sstr2, sstr3, sstr4 ); - gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), 128 ); + snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); + gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), MSG_BUF_SIZE ); break; case HUD_PRINTCONSOLE: - sprintf( psz, msg_text, sstr1, sstr2, sstr3, sstr4 ); + snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); ConsolePrint( ConvertCRtoNL( psz ) ); break; } From cf9ba716862eb50da691a4daff272a61f0a0b674 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Fri, 21 Jul 2017 00:52:09 +0500 Subject: [PATCH 099/211] Make UpdateOnRemove() virtual. --- cl_dll/hl/hl_baseentity.cpp | 1 + dlls/cbase.h | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cl_dll/hl/hl_baseentity.cpp b/cl_dll/hl/hl_baseentity.cpp index d24c0ef4..acd537e0 100644 --- a/cl_dll/hl/hl_baseentity.cpp +++ b/cl_dll/hl/hl_baseentity.cpp @@ -55,6 +55,7 @@ BOOL CBaseEntity::IsInWorld( void ) { return TRUE; } int CBaseEntity::ShouldToggle( USE_TYPE useType, BOOL currentState ) { return 0; } int CBaseEntity::DamageDecal( int bitsDamageType ) { return -1; } CBaseEntity *CBaseEntity::Create( const char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) { return NULL; } +void CBaseEntity::UpdateOnRemove( void ) { } void CBaseEntity::SUB_Remove( void ) { } // CBaseDelay Stubs diff --git a/dlls/cbase.h b/dlls/cbase.h index 6c738bf5..b78de883 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -12,6 +12,8 @@ * without written permission from Valve LLC. * ****/ +#ifndef CBASE_H +#define CBASE_H /* Class Hierachy @@ -229,7 +231,7 @@ public: }; #endif - void UpdateOnRemove( void ); + virtual void UpdateOnRemove( void ); // common member functions void EXPORT SUB_Remove( void ); @@ -780,3 +782,4 @@ public: void Precache( void ); void KeyValue( KeyValueData *pkvd ); }; +#endif From 70c6e429076e746b1be4492b0c6f468ef7ea2174 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 23 Jul 2017 21:41:05 +0500 Subject: [PATCH 100/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/68c9b7cf6bdcacdf267c2e2dab2415dbbebdfcd2 --- cl_dll/hl/hl_baseentity.cpp | 2 +- dlls/handgrenade.cpp | 3 +- dlls/player.cpp | 20 +++++---- dlls/player.h | 2 +- dlls/satchel.cpp | 83 +++++++++++++++++-------------------- dlls/squeakgrenade.cpp | 3 +- dlls/tripmine.cpp | 3 +- dlls/weapons.cpp | 18 ++++++-- 8 files changed, 68 insertions(+), 66 deletions(-) diff --git a/cl_dll/hl/hl_baseentity.cpp b/cl_dll/hl/hl_baseentity.cpp index acd537e0..38978f6a 100644 --- a/cl_dll/hl/hl_baseentity.cpp +++ b/cl_dll/hl/hl_baseentity.cpp @@ -277,7 +277,7 @@ void CBasePlayer::ForceClientDllUpdate( void ) { } void CBasePlayer::ImpulseCommands() { } void CBasePlayer::CheatImpulseCommands( int iImpulse ) { } int CBasePlayer::AddPlayerItem( CBasePlayerItem *pItem ) { return FALSE; } -int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) { return FALSE; } +int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem, bool bCallHoster ) { return FALSE; } void CBasePlayer::ItemPreFrame() { } void CBasePlayer::ItemPostFrame() { } int CBasePlayer::AmmoInventory( int iAmmoIndex ) { return -1; } diff --git a/dlls/handgrenade.cpp b/dlls/handgrenade.cpp index 2a31fc84..c2bbd7f9 100644 --- a/dlls/handgrenade.cpp +++ b/dlls/handgrenade.cpp @@ -99,8 +99,7 @@ void CHandGrenade::Holster( int skiplocal /* = 0 */ ) { // no more grenades! m_pPlayer->pev->weapons &= ~( 1 << WEAPON_HANDGRENADE ); - SetThink( &CBasePlayerItem::DestroyItem ); - pev->nextthink = gpGlobals->time + 0.1; + DestroyItem(); } if( m_flStartThrow ) diff --git a/dlls/player.cpp b/dlls/player.cpp index 1a7bc206..38038b36 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -666,8 +666,8 @@ void CBasePlayer::PackDeadPlayerItems( void ) int iWeaponRules; int iAmmoRules; int i; - CBasePlayerWeapon *rgpPackWeapons[20] = {0};// 20 hardcoded for now. How to determine exactly how many weapons we have? - int iPackAmmo[MAX_AMMO_SLOTS + 1]; + CBasePlayerWeapon *rgpPackWeapons[MAX_WEAPONS] = {}; + int iPackAmmo[MAX_AMMO_SLOTS]; int iPW = 0;// index into packweapons array int iPA = 0;// index into packammo array @@ -675,7 +675,7 @@ void CBasePlayer::PackDeadPlayerItems( void ) // get the game rules iWeaponRules = g_pGameRules->DeadPlayerWeapons( this ); - iAmmoRules = g_pGameRules->DeadPlayerAmmo( this ); + iAmmoRules = g_pGameRules->DeadPlayerAmmo( this ); if( iWeaponRules == GR_PLR_DROP_GUN_NO && iAmmoRules == GR_PLR_DROP_AMMO_NO ) { @@ -685,14 +685,14 @@ void CBasePlayer::PackDeadPlayerItems( void ) } // go through all of the weapons and make a list of the ones to pack - for( i = 0; i < MAX_ITEM_TYPES; i++ ) + for( i = 0; i < MAX_ITEM_TYPES && iPW < MAX_WEAPONS; i++ ) { if( m_rgpPlayerItems[i] ) { // there's a weapon here. Should I pack it? CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[i]; - while( pPlayerItem ) + while( pPlayerItem && iPW < MAX_WEAPONS ) { switch( iWeaponRules ) { @@ -3640,14 +3640,16 @@ int CBasePlayer::AddPlayerItem( CBasePlayerItem *pItem ) return FALSE; } -int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) +int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem, bool bCallHolster ) { + pItem->pev->nextthink = 0;// crowbar may be trying to swing again, etc. + pItem->SetThink( NULL ); + if( m_pActiveItem == pItem ) { ResetAutoaim(); - pItem->Holster(); - pItem->pev->nextthink = 0;// crowbar may be trying to swing again, etc. - pItem->SetThink( NULL ); + if( bCallHolster ) + pItem->Holster(); m_pActiveItem = NULL; pev->viewmodel = 0; pev->weaponmodel = 0; diff --git a/dlls/player.h b/dlls/player.h index 8ff312ea..1c17556c 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -259,7 +259,7 @@ public: void AddPoints( int score, BOOL bAllowNegativeScore ); void AddPointsToTeam( int score, BOOL bAllowNegativeScore ); BOOL AddPlayerItem( CBasePlayerItem *pItem ); - BOOL RemovePlayerItem( CBasePlayerItem *pItem ); + BOOL RemovePlayerItem( CBasePlayerItem *pItem, bool bCallHoster ); void DropPlayerItem ( char *pszItemName ); BOOL HasPlayerItem( CBasePlayerItem *pCheckItem ); BOOL HasNamedPlayerItem( const char *pszItemName ); diff --git a/dlls/satchel.cpp b/dlls/satchel.cpp index 015b3483..dc8724bd 100644 --- a/dlls/satchel.cpp +++ b/dlls/satchel.cpp @@ -23,6 +23,13 @@ #include "player.h" #include "gamerules.h" +enum satchel_state +{ + SATCHEL_IDLE = 0, + SATCHEL_READY, + SATCHEL_RELOAD +}; + enum satchel_e { SATCHEL_IDLE1 = 0, @@ -194,7 +201,7 @@ int CSatchel::AddDuplicate( CBasePlayerItem *pOriginal ) { pSatchel = (CSatchel *)pOriginal; - if( pSatchel->m_chargeReady != 0 ) + if( pSatchel->m_chargeReady != SATCHEL_IDLE ) { // player has some satchels deployed. Refuse to add more. return FALSE; @@ -211,7 +218,7 @@ int CSatchel::AddToPlayer( CBasePlayer *pPlayer ) int bResult = CBasePlayerItem::AddToPlayer( pPlayer ); pPlayer->pev->weapons |= ( 1 << m_iId ); - m_chargeReady = 0;// this satchel charge weapon now forgets that any satchels are deployed by it. + m_chargeReady = SATCHEL_IDLE;// this satchel charge weapon now forgets that any satchels are deployed by it. if( bResult ) { @@ -263,19 +270,7 @@ int CSatchel::GetItemInfo( ItemInfo *p ) //========================================================= BOOL CSatchel::IsUseable( void ) { - if( m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] > 0 ) - { - // player is carrying some satchels - return TRUE; - } - - if( m_chargeReady != 0 ) - { - // player isn't carrying any satchels, but has some out - return TRUE; - } - - return FALSE; + return CanDeploy(); } BOOL CSatchel::CanDeploy( void ) @@ -286,7 +281,7 @@ BOOL CSatchel::CanDeploy( void ) return TRUE; } - if( m_chargeReady != 0 ) + if( m_chargeReady ) { // player isn't carrying any satchels, but has some out return TRUE; @@ -322,11 +317,10 @@ void CSatchel::Holster( int skiplocal /* = 0 */ ) } EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "common/null.wav", 1.0, ATTN_NORM ); - if( !m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] && !m_chargeReady ) + if( !m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] && m_chargeReady != SATCHEL_READY ) { m_pPlayer->pev->weapons &= ~( 1 << WEAPON_SATCHEL ); - SetThink( &CBasePlayerItem::DestroyItem ); - pev->nextthink = gpGlobals->time + 0.1; + DestroyItem(); } } @@ -334,38 +328,37 @@ void CSatchel::PrimaryAttack() { switch( m_chargeReady ) { - case 0: + case SATCHEL_IDLE: { - Throw(); + Throw(); } break; - case 1: + case SATCHEL_READY: { - SendWeaponAnim( SATCHEL_RADIO_FIRE ); + SendWeaponAnim( SATCHEL_RADIO_FIRE ); - edict_t *pPlayer = m_pPlayer->edict(); + edict_t *pPlayer = m_pPlayer->edict(); - CBaseEntity *pSatchel = NULL; + CBaseEntity *pSatchel = NULL; - while( ( pSatchel = UTIL_FindEntityInSphere( pSatchel, m_pPlayer->pev->origin, 4096 ) ) != NULL ) - { - if( FClassnameIs( pSatchel->pev, "monster_satchel" ) ) + while( ( pSatchel = UTIL_FindEntityInSphere( pSatchel, m_pPlayer->pev->origin, 4096 ) ) != NULL ) { - if( pSatchel->pev->owner == pPlayer ) + if( FClassnameIs( pSatchel->pev, "monster_satchel" ) ) { - pSatchel->Use( m_pPlayer, m_pPlayer, USE_ON, 0 ); - m_chargeReady = 2; + if( pSatchel->pev->owner == pPlayer ) + { + pSatchel->Use( m_pPlayer, m_pPlayer, USE_ON, 0 ); + } } } - } - m_chargeReady = 2; - m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); - m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5; - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5; - break; + m_chargeReady = SATCHEL_RELOAD; + m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); + m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5; + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5; + break; } - case 2: + case SATCHEL_RELOAD: // we're reloading, don't allow fire break; } @@ -373,7 +366,7 @@ void CSatchel::PrimaryAttack() void CSatchel::SecondaryAttack( void ) { - if( m_chargeReady != 2 ) + if( m_chargeReady != SATCHEL_RELOAD ) { Throw(); } @@ -403,8 +396,8 @@ void CSatchel::Throw( void ) // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - m_chargeReady = 1; - + m_chargeReady = SATCHEL_READY; + m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; m_flNextPrimaryAttack = GetNextAttackDelay( 1.0 ); @@ -419,17 +412,17 @@ void CSatchel::WeaponIdle( void ) switch( m_chargeReady ) { - case 0: + case SATCHEL_IDLE: SendWeaponAnim( SATCHEL_FIDGET1 ); // use tripmine animations strcpy( m_pPlayer->m_szAnimExtention, "trip" ); break; - case 1: + case SATCHEL_READY: SendWeaponAnim( SATCHEL_RADIO_FIDGET1 ); // use hivehand animations strcpy( m_pPlayer->m_szAnimExtention, "hive" ); break; - case 2: + case SATCHEL_RELOAD: if( !m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ) { m_chargeReady = 0; @@ -450,7 +443,7 @@ void CSatchel::WeaponIdle( void ) m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5; - m_chargeReady = 0; + m_chargeReady = SATCHEL_IDLE; break; } m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );// how long till we do this again. diff --git a/dlls/squeakgrenade.cpp b/dlls/squeakgrenade.cpp index 830cfab8..bfe17ed1 100644 --- a/dlls/squeakgrenade.cpp +++ b/dlls/squeakgrenade.cpp @@ -475,8 +475,7 @@ void CSqueak::Holster( int skiplocal /* = 0 */ ) if( !m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ) { m_pPlayer->pev->weapons &= ~( 1 << WEAPON_SNARK ); - SetThink( &CBasePlayerItem::DestroyItem ); - pev->nextthink = gpGlobals->time + 0.1; + DestroyItem(); return; } diff --git a/dlls/tripmine.cpp b/dlls/tripmine.cpp index 60190604..94907bcd 100644 --- a/dlls/tripmine.cpp +++ b/dlls/tripmine.cpp @@ -418,8 +418,7 @@ void CTripmine::Holster( int skiplocal /* = 0 */ ) { // out of mines m_pPlayer->pev->weapons &= ~( 1 << WEAPON_TRIPMINE ); - SetThink( &CBasePlayerItem::DestroyItem ); - pev->nextthink = gpGlobals->time + 0.1; + DestroyItem(); } SendWeaponAnim( TRIPMINE_HOLSTER ); diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 05db43da..06bb1796 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -688,8 +688,8 @@ void CBasePlayerItem::DestroyItem( void ) { if( m_pPlayer ) { - // if attached to a player, remove. - m_pPlayer->RemovePlayerItem( this ); + // if attached to a player, remove. + m_pPlayer->RemovePlayerItem( this, false ); } Kill(); @@ -1140,7 +1140,17 @@ void CBasePlayerWeapon::RetireWeapon( void ) m_pPlayer->pev->weaponmodel = iStringNull; //m_pPlayer->pev->viewmodelindex = NULL; - g_pGameRules->GetNextBestWeapon( m_pPlayer, this ); + if( !g_pGameRules->GetNextBestWeapon( m_pPlayer, this ) ) + { + // Another weapon wasn't selected. Get rid of current one + if( m_pPlayer->m_pActiveItem == this ) + { + m_pPlayer->ResetAutoaim(); + m_pPlayer->m_pActiveItem->Holster(); + m_pPlayer->m_pLastItem = NULL; + m_pPlayer->m_pActiveItem = NULL; + } + } } //========================================================================= @@ -1340,7 +1350,7 @@ BOOL CWeaponBox::PackWeapon( CBasePlayerItem *pWeapon ) if( pWeapon->m_pPlayer ) { - if( !pWeapon->m_pPlayer->RemovePlayerItem( pWeapon ) ) + if( !pWeapon->m_pPlayer->RemovePlayerItem( pWeapon, true ) ) { // failed to unhook the weapon from the player! return FALSE; From 49e740c6f132969f7881c21ad3bdecb6aad84568 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 24 Jul 2017 02:24:55 +0500 Subject: [PATCH 101/211] Remove unneeded casts. --- dlls/agrunt.cpp | 14 ++++++------- dlls/animation.cpp | 2 +- dlls/bmodels.cpp | 16 +++++++-------- dlls/buttons.cpp | 26 +++++++++++------------ dlls/cbase.cpp | 2 +- dlls/doors.cpp | 28 ++++++++++++------------- dlls/effects.cpp | 25 +++++++++++----------- dlls/func_break.cpp | 8 ++++---- dlls/func_tank.cpp | 10 ++++----- dlls/gargantua.cpp | 22 ++++++++++---------- dlls/genericmonster.cpp | 2 +- dlls/h_cycler.cpp | 10 ++++----- dlls/islave.cpp | 8 ++++---- dlls/leech.cpp | 4 ++-- dlls/multiplay_gamerules.cpp | 28 ++++++++++++------------- dlls/nodes.cpp | 8 ++++---- dlls/nodes.h | 6 +++--- dlls/plats.cpp | 40 ++++++++++++++++++------------------ dlls/prop.cpp | 6 +++--- dlls/scripted.cpp | 4 ++-- dlls/sound.cpp | 8 ++++---- dlls/stats.cpp | 4 ++-- dlls/triggers.cpp | 8 ++++---- dlls/util.cpp | 10 ++++----- dlls/util.h | 2 +- dlls/weapons.cpp | 8 ++++---- dlls/world.cpp | 4 ++-- dlls/xen.cpp | 6 +++--- dlls/zombie.cpp | 14 ++++++------- 29 files changed, 166 insertions(+), 167 deletions(-) diff --git a/dlls/agrunt.cpp b/dlls/agrunt.cpp index c6583fb7..cb47ac65 100644 --- a/dlls/agrunt.cpp +++ b/dlls/agrunt.cpp @@ -613,25 +613,25 @@ void CAGrunt::Precache() PRECACHE_MODEL( "models/agrunt.mdl" ); for( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackHitSounds[i] ); + PRECACHE_SOUND( pAttackHitSounds[i] ); for( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackMissSounds[i] ); + PRECACHE_SOUND( pAttackMissSounds[i] ); for( i = 0; i < ARRAYSIZE( pIdleSounds ); i++ ) - PRECACHE_SOUND( (char *)pIdleSounds[i] ); + PRECACHE_SOUND( pIdleSounds[i] ); for( i = 0; i < ARRAYSIZE( pDieSounds ); i++ ) - PRECACHE_SOUND( (char *)pDieSounds[i] ); + PRECACHE_SOUND( pDieSounds[i] ); for( i = 0; i < ARRAYSIZE( pPainSounds ); i++ ) - PRECACHE_SOUND( (char *)pPainSounds[i] ); + PRECACHE_SOUND( pPainSounds[i] ); for( i = 0; i < ARRAYSIZE( pAttackSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackSounds[i] ); + PRECACHE_SOUND( pAttackSounds[i] ); for( i = 0; i < ARRAYSIZE( pAlertSounds ); i++ ) - PRECACHE_SOUND( (char *)pAlertSounds[i] ); + PRECACHE_SOUND( pAlertSounds[i] ); PRECACHE_SOUND( "hassault/hw_shoot1.wav" ); diff --git a/dlls/animation.cpp b/dlls/animation.cpp index 5454f0e8..f84ec380 100644 --- a/dlls/animation.cpp +++ b/dlls/animation.cpp @@ -208,7 +208,7 @@ void SequencePrecache( void *pmodel, const char *pSequenceName ) ALERT( at_error, "Bad sound event %d in sequence %s :: %s (sound is \"%s\")\n", pevent[i].event, pstudiohdr->name, pSequenceName, pevent[i].options ); } - PRECACHE_SOUND( (char *)( gpGlobals->pStringBase + ALLOC_STRING( pevent[i].options ) ) ); + PRECACHE_SOUND( gpGlobals->pStringBase + ALLOC_STRING( pevent[i].options ) ); } } } diff --git a/dlls/bmodels.cpp b/dlls/bmodels.cpp index c48abbf9..fe56b6ac 100644 --- a/dlls/bmodels.cpp +++ b/dlls/bmodels.cpp @@ -402,7 +402,7 @@ void CFuncRotating::Spawn() } UTIL_SetOrigin( pev, pev->origin ); - SET_MODEL( ENT(pev), STRING(pev->model) ); + SET_MODEL( ENT( pev ), STRING( pev->model ) ); SetUse( &CFuncRotating::RotatingUse ); // did level designer forget to assign speed? @@ -538,7 +538,7 @@ void CFuncRotating::RampPitchVol( int fUp ) pitch = PITCH_NORM - 1; // change the fan's vol and pitch - EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char *)STRING( pev->noiseRunning ), + EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, STRING( pev->noiseRunning ), fvol, m_flAttenuation, SND_CHANGE_PITCH | SND_CHANGE_VOL, pitch ); } @@ -560,7 +560,7 @@ void CFuncRotating::SpinUp( void ) fabs( vecAVel.z ) >= fabs( pev->movedir.z * pev->speed ) ) { pev->avelocity = pev->movedir * pev->speed;// set speed in case we overshot - EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char *)STRING( pev->noiseRunning ), + EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, STRING( pev->noiseRunning ), m_flVolume, m_flAttenuation, SND_CHANGE_PITCH | SND_CHANGE_VOL, FANPITCHMAX ); SetThink( &CFuncRotating::Rotate ); @@ -601,7 +601,7 @@ void CFuncRotating::SpinDown( void ) pev->avelocity = g_vecZero;// set speed in case we overshot // stop sound, we're done - EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char *)STRING( pev->noiseRunning /* Stop */ ), + EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, STRING( pev->noiseRunning /* Stop */ ), 0, 0, SND_STOP, (int)m_pitch ); SetThink( &CFuncRotating::Rotate ); @@ -630,7 +630,7 @@ void CFuncRotating::RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, if( pev->avelocity != g_vecZero ) { SetThink( &CFuncRotating::SpinDown ); - //EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, (char *)STRING( pev->noiseStop ), + //EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, STRING( pev->noiseStop ), // m_flVolume, m_flAttenuation, 0, m_pitch ); pev->nextthink = pev->ltime + 0.1; @@ -638,7 +638,7 @@ void CFuncRotating::RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, else// fan is not moving, so start it { SetThink( &CFuncRotating::SpinUp ); - EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char *)STRING( pev->noiseRunning ), + EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, STRING( pev->noiseRunning ), 0.01, m_flAttenuation, 0, FANPITCHMIN ); pev->nextthink = pev->ltime + 0.1; @@ -651,7 +651,7 @@ void CFuncRotating::RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, // play stopping sound here SetThink( &CFuncRotating::SpinDown ); - // EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, (char *)STRING( pev->noiseStop ), + // EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, STRING( pev->noiseStop ), // m_flVolume, m_flAttenuation, 0, m_pitch ); pev->nextthink = pev->ltime + 0.1; @@ -659,7 +659,7 @@ void CFuncRotating::RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, } else { - EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char *)STRING( pev->noiseRunning ), + EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, STRING( pev->noiseRunning ), m_flVolume, m_flAttenuation, 0, FANPITCHMAX ); pev->avelocity = pev->movedir * pev->speed; diff --git a/dlls/buttons.cpp b/dlls/buttons.cpp index 7ea9082a..90bc42e5 100644 --- a/dlls/buttons.cpp +++ b/dlls/buttons.cpp @@ -343,25 +343,25 @@ void CBaseButton::Precache( void ) m_ls.sUnlockedSentence = MAKE_STRING( "EA" ); break; case 2: // security door - m_ls.sUnlockedSentence = MAKE_STRING("ED"); + m_ls.sUnlockedSentence = MAKE_STRING( "ED" ); break; case 3: // blast door - m_ls.sUnlockedSentence = MAKE_STRING("EF"); + m_ls.sUnlockedSentence = MAKE_STRING( "EF" ); break; case 4: // fire door - m_ls.sUnlockedSentence = MAKE_STRING("EFIRE"); + m_ls.sUnlockedSentence = MAKE_STRING( "EFIRE" ); break; case 5: // chemical door - m_ls.sUnlockedSentence = MAKE_STRING("ECHEM"); + m_ls.sUnlockedSentence = MAKE_STRING( "ECHEM" ); break; case 6: // radiation door - m_ls.sUnlockedSentence = MAKE_STRING("ERAD"); + m_ls.sUnlockedSentence = MAKE_STRING( "ERAD" ); break; case 7: // gen containment - m_ls.sUnlockedSentence = MAKE_STRING("ECON"); + m_ls.sUnlockedSentence = MAKE_STRING( "ECON" ); break; case 8: // maintenance door - m_ls.sUnlockedSentence = MAKE_STRING("EH"); + m_ls.sUnlockedSentence = MAKE_STRING( "EH" ); break; default: m_ls.sUnlockedSentence = 0; @@ -426,7 +426,7 @@ int CBaseButton::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, fl if( code == BUTTON_RETURN ) { - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noise ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noise ), 1, ATTN_NORM ); // Toggle buttons fire when they get back to their "home" position if( !( pev->spawnflags & SF_BUTTON_TOGGLE ) ) @@ -657,7 +657,7 @@ void CBaseButton::ButtonUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_ { if( !m_fStayPushed && FBitSet( pev->spawnflags, SF_BUTTON_TOGGLE ) ) { - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noise ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noise ), 1, ATTN_NORM ); //SUB_UseTargets( m_eoActivator ); ButtonReturn(); @@ -716,7 +716,7 @@ void CBaseButton::ButtonTouch( CBaseEntity *pOther ) if( code == BUTTON_RETURN ) { - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noise ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noise ), 1, ATTN_NORM ); SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); ButtonReturn(); } @@ -729,7 +729,7 @@ void CBaseButton::ButtonTouch( CBaseEntity *pOther ) // void CBaseButton::ButtonActivate() { - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noise ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noise ), 1, ATTN_NORM ); if( !UTIL_IsMasterTriggered( m_sMaster, m_hActivator ) ) { @@ -815,7 +815,7 @@ void CBaseButton::ButtonBackHome( void ) if( FBitSet( pev->spawnflags, SF_BUTTON_TOGGLE ) ) { - //EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noise ), 1, ATTN_NORM ); + //EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noise ), 1, ATTN_NORM ); SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); } @@ -1034,7 +1034,7 @@ void CMomentaryRotButton::KeyValue( KeyValueData *pkvd ) void CMomentaryRotButton::PlaySound( void ) { - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noise ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noise ), 1, ATTN_NORM ); } // BUGBUG: This design causes a latentcy. When the button is retriggered, the first impulse diff --git a/dlls/cbase.cpp b/dlls/cbase.cpp index 6009bfd5..8750bddf 100644 --- a/dlls/cbase.cpp +++ b/dlls/cbase.cpp @@ -605,7 +605,7 @@ int CBaseEntity::Restore( CRestore &restore ) mins = pev->mins; // Set model is about to destroy these maxs = pev->maxs; - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); UTIL_SetSize( pev, mins, maxs ); // Reset them } diff --git a/dlls/doors.cpp b/dlls/doors.cpp index 90678df6..c12cc3a0 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -127,7 +127,7 @@ void PlayLockSounds( entvars_t *pev, locksound_t *pls, int flocked, int fbutton if( fplaysound ) { // play 'door locked' sound - EMIT_SOUND( ENT( pev ), CHAN_ITEM, (char*)STRING( pls->sLockedSound ), fvol, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_ITEM, STRING( pls->sLockedSound ), fvol, ATTN_NORM ); pls->flwaitSound = gpGlobals->time + flsoundwait; } @@ -164,7 +164,7 @@ void PlayLockSounds( entvars_t *pev, locksound_t *pls, int flocked, int fbutton // play 'door unlocked' sound if set if( fplaysound ) { - EMIT_SOUND( ENT( pev ), CHAN_ITEM, (char*)STRING( pls->sUnlockedSound ), fvol, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_ITEM, STRING( pls->sUnlockedSound ), fvol, ATTN_NORM ); pls->flwaitSound = gpGlobals->time + flsoundwait; } @@ -606,7 +606,7 @@ void CBaseDoor::DoorGoUp( void ) // filter them out and leave a client stuck with looping door sounds! if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) if( m_toggle_state != TS_GOING_UP && m_toggle_state != TS_GOING_DOWN ) - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ), 1, ATTN_NORM ); m_toggle_state = TS_GOING_UP; @@ -646,8 +646,8 @@ void CBaseDoor::DoorHitTop( void ) { if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) { - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ) ); - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseArrived ), 1, ATTN_NORM ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ) ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseArrived ), 1, ATTN_NORM ); } ASSERT( m_toggle_state == TS_GOING_UP ); @@ -686,7 +686,7 @@ void CBaseDoor::DoorGoDown( void ) { if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) if( m_toggle_state != TS_GOING_UP && m_toggle_state != TS_GOING_DOWN ) - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ), 1, ATTN_NORM ); #ifdef DOOR_ASSERT ASSERT( m_toggle_state == TS_AT_TOP ); #endif // DOOR_ASSERT @@ -706,8 +706,8 @@ void CBaseDoor::DoorHitBottom( void ) { if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) { - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ) ); - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseArrived ), 1, ATTN_NORM ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ) ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseArrived ), 1, ATTN_NORM ); } ASSERT( m_toggle_state == TS_GOING_DOWN ); @@ -751,7 +751,7 @@ void CBaseDoor::Blocked( CBaseEntity *pOther ) { // BMod Start - Door sound fix. if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ) ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ) ); // BMod End if( m_toggle_state == TS_GOING_DOWN ) @@ -767,7 +767,7 @@ void CBaseDoor::Blocked( CBaseEntity *pOther ) // Block all door pieces with the same targetname here. if( !FStringNull( pev->targetname ) ) { - for(;;) + for( ; ; ) { pentTarget = FIND_ENTITY_BY_TARGETNAME( pentTarget, STRING( pev->targetname ) ); @@ -799,7 +799,7 @@ void CBaseDoor::Blocked( CBaseEntity *pOther ) } } if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ) ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ) ); if( pDoor->m_toggle_state == TS_GOING_DOWN ) pDoor->DoorGoUp(); @@ -1106,7 +1106,7 @@ void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP // This entity only thinks when it moves, so if it's thinking, it's in the process of moving // play the sound when it starts moving(not yet thinking) if( pev->nextthink < pev->ltime || pev->nextthink == 0 ) - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ), 1, ATTN_NORM ); // If we already moving to designated point, return else if( move == m_vecFinalDest ) return; @@ -1118,6 +1118,6 @@ void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP void CMomentaryDoor::MomentaryMoveDone( void ) { - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMoving ) ); - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseArrived ), 1, ATTN_NORM ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ) ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseArrived ), 1, ATTN_NORM ); } diff --git a/dlls/effects.cpp b/dlls/effects.cpp index 2977a3ed..c3216835 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -229,7 +229,7 @@ void CBeam::BeamInit( const char *pSpriteName, int width ) SetFrame( 0 ); SetScrollRate( 0 ); pev->model = MAKE_STRING( pSpriteName ); - SetTexture( PRECACHE_MODEL( (char *)pSpriteName ) ); + SetTexture( PRECACHE_MODEL( pSpriteName ) ); SetWidth( width ); pev->skin = 0; pev->sequence = 0; @@ -486,7 +486,7 @@ void CLightning::Spawn( void ) void CLightning::Precache( void ) { - m_spriteTexture = PRECACHE_MODEL( (char *)STRING( m_iszSpriteName ) ); + m_spriteTexture = PRECACHE_MODEL( STRING( m_iszSpriteName ) ); CBeam::Precache(); } @@ -954,9 +954,9 @@ void CLaser::Spawn( void ) void CLaser::Precache( void ) { - pev->modelindex = PRECACHE_MODEL( (char *)STRING( pev->model ) ); + pev->modelindex = PRECACHE_MODEL( STRING( pev->model ) ); if( m_iszSpriteName ) - PRECACHE_MODEL( (char *)STRING( m_iszSpriteName ) ); + PRECACHE_MODEL( STRING( m_iszSpriteName ) ); } void CLaser::KeyValue( KeyValueData *pkvd ) @@ -1100,7 +1100,7 @@ void CGlow::Spawn( void ) pev->effects = 0; pev->frame = 0; - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1; @@ -1160,7 +1160,7 @@ void CSprite::Spawn( void ) void CSprite::Precache( void ) { - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); // Reset attachment after save/restore if( pev->aiment ) @@ -1515,7 +1515,7 @@ void CEnvShooter::KeyValue( KeyValueData *pkvd ) void CEnvShooter::Precache( void ) { - m_iGibModelIndex = PRECACHE_MODEL( (char *)STRING( pev->model ) ); + m_iGibModelIndex = PRECACHE_MODEL( STRING( pev->model ) ); CBreakable::MaterialSoundPrecache( (Materials)m_iGibMaterial ); } @@ -2005,7 +2005,7 @@ void CMessage::Spawn( void ) void CMessage::Precache( void ) { if( pev->noise ) - PRECACHE_SOUND( (char *)STRING( pev->noise ) ); + PRECACHE_SOUND( STRING( pev->noise ) ); } void CMessage::KeyValue( KeyValueData *pkvd ) @@ -2040,16 +2040,15 @@ void CMessage::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT if( pActivator && pActivator->IsPlayer() ) pPlayer = pActivator; else - { pPlayer = CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) ); - } + if( pPlayer ) UTIL_ShowMessage( STRING( pev->message ), pPlayer ); } + if( pev->noise ) - { EMIT_SOUND( edict(), CHAN_BODY, STRING( pev->noise ), pev->scale, pev->speed ); - } + if( pev->spawnflags & SF_MESSAGE_ONCE ) UTIL_Remove( this ); @@ -2071,7 +2070,7 @@ public: void CEnvFunnel::Precache( void ) { - m_iSprite = PRECACHE_MODEL ( "sprites/flare6.spr" ); + m_iSprite = PRECACHE_MODEL( "sprites/flare6.spr" ); } LINK_ENTITY_TO_CLASS( env_funnel, CEnvFunnel ) diff --git a/dlls/func_break.cpp b/dlls/func_break.cpp index 6abf1b44..0cc3675f 100644 --- a/dlls/func_break.cpp +++ b/dlls/func_break.cpp @@ -259,7 +259,7 @@ void CBreakable::MaterialSoundPrecache( Materials precacheMaterial ) for( i = 0; i < soundCount; i++ ) { - PRECACHE_SOUND( (char *)pSoundList[i] ); + PRECACHE_SOUND( pSoundList[i] ); } } @@ -340,11 +340,11 @@ void CBreakable::Precache( void ) if( m_iszGibModel ) pGibName = STRING( m_iszGibModel ); - m_idShard = PRECACHE_MODEL( (char *)pGibName ); + m_idShard = PRECACHE_MODEL( pGibName ); // Precache the spawn item's data if( m_iszSpawnObject ) - UTIL_PrecacheOther( (char *)STRING( m_iszSpawnObject ) ); + UTIL_PrecacheOther( STRING( m_iszSpawnObject ) ); } // play shard sound when func_breakable takes damage. @@ -746,7 +746,7 @@ void CBreakable::Die( void ) SetThink( &CBaseEntity::SUB_Remove ); pev->nextthink = pev->ltime + 0.1; if( m_iszSpawnObject ) - CBaseEntity::Create( (char *)STRING( m_iszSpawnObject ), VecBModelOrigin( pev ), pev->angles, edict() ); + CBaseEntity::Create( STRING( m_iszSpawnObject ), VecBModelOrigin( pev ), pev->angles, edict() ); if( Explodable() ) { diff --git a/dlls/func_tank.cpp b/dlls/func_tank.cpp index c4e3cb42..6eebc675 100644 --- a/dlls/func_tank.cpp +++ b/dlls/func_tank.cpp @@ -200,13 +200,13 @@ void CFuncTank::Spawn( void ) void CFuncTank::Precache( void ) { if( m_iszSpriteSmoke ) - PRECACHE_MODEL( (char *)STRING( m_iszSpriteSmoke ) ); + PRECACHE_MODEL( STRING( m_iszSpriteSmoke ) ); if( m_iszSpriteFlash ) - PRECACHE_MODEL( (char *)STRING( m_iszSpriteFlash ) ); + PRECACHE_MODEL( STRING( m_iszSpriteFlash ) ); if( pev->noise ) - PRECACHE_SOUND( (char *)STRING( pev->noise ) ); + PRECACHE_SOUND( STRING( pev->noise ) ); } void CFuncTank::KeyValue( KeyValueData *pkvd ) @@ -688,13 +688,13 @@ void CFuncTank::StartRotSound( void ) if( !pev->noise || ( pev->spawnflags & SF_TANK_SOUNDON ) ) return; pev->spawnflags |= SF_TANK_SOUNDON; - EMIT_SOUND( edict(), CHAN_STATIC, (char*)STRING( pev->noise ), 0.85, ATTN_NORM ); + EMIT_SOUND( edict(), CHAN_STATIC, STRING( pev->noise ), 0.85, ATTN_NORM ); } void CFuncTank::StopRotSound( void ) { if( pev->spawnflags & SF_TANK_SOUNDON ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING( pev->noise ) ); + STOP_SOUND( edict(), CHAN_STATIC, STRING( pev->noise ) ); pev->spawnflags &= ~SF_TANK_SOUNDON; } diff --git a/dlls/gargantua.cpp b/dlls/gargantua.cpp index 6aa6a738..f3155d7f 100644 --- a/dlls/gargantua.cpp +++ b/dlls/gargantua.cpp @@ -770,37 +770,37 @@ void CGargantua::Precache() PRECACHE_SOUND( GARG_STOMP_BUZZ_SOUND ); for( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackHitSounds[i] ); + PRECACHE_SOUND( pAttackHitSounds[i] ); for( i = 0; i < ARRAYSIZE( pBeamAttackSounds ); i++ ) - PRECACHE_SOUND( (char *)pBeamAttackSounds[i] ); + PRECACHE_SOUND( pBeamAttackSounds[i] ); for( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackMissSounds[i] ); + PRECACHE_SOUND( pAttackMissSounds[i] ); for( i = 0; i < ARRAYSIZE( pRicSounds ); i++ ) - PRECACHE_SOUND( (char *)pRicSounds[i] ); + PRECACHE_SOUND( pRicSounds[i] ); for( i = 0; i < ARRAYSIZE( pFootSounds ); i++ ) - PRECACHE_SOUND( (char *)pFootSounds[i] ); + PRECACHE_SOUND( pFootSounds[i] ); for( i = 0; i < ARRAYSIZE( pIdleSounds ); i++ ) - PRECACHE_SOUND( (char *)pIdleSounds[i] ); + PRECACHE_SOUND( pIdleSounds[i] ); for( i = 0; i < ARRAYSIZE( pAlertSounds ); i++ ) - PRECACHE_SOUND((char *)pAlertSounds[i]); + PRECACHE_SOUND( pAlertSounds[i] ); for( i = 0; i < ARRAYSIZE( pPainSounds ); i++ ) - PRECACHE_SOUND( (char *)pPainSounds[i] ); + PRECACHE_SOUND( pPainSounds[i] ); for( i = 0; i < ARRAYSIZE( pAttackSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackSounds[i] ); + PRECACHE_SOUND( pAttackSounds[i] ); for( i = 0; i < ARRAYSIZE( pStompSounds ); i++ ) - PRECACHE_SOUND( (char *)pStompSounds[i] ); + PRECACHE_SOUND( pStompSounds[i] ); for( i = 0; i < ARRAYSIZE( pBreatheSounds ); i++ ) - PRECACHE_SOUND( (char *)pBreatheSounds[i] ); + PRECACHE_SOUND( pBreatheSounds[i] ); } void CGargantua::UpdateOnRemove() diff --git a/dlls/genericmonster.cpp b/dlls/genericmonster.cpp index 23622120..3cc0acc6 100644 --- a/dlls/genericmonster.cpp +++ b/dlls/genericmonster.cpp @@ -131,7 +131,7 @@ void CGenericMonster::Spawn() //========================================================= void CGenericMonster::Precache() { - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); } //========================================================= diff --git a/dlls/h_cycler.cpp b/dlls/h_cycler.cpp index e920abfa..5daad4a2 100644 --- a/dlls/h_cycler.cpp +++ b/dlls/h_cycler.cpp @@ -67,7 +67,7 @@ class CGenericCycler : public CCycler public: void Spawn( void ) { - GenericCyclerSpawn( (char *)STRING( pev->model ), Vector( -16, -16, 0 ), Vector( 16, 16, 72 ) ); + GenericCyclerSpawn( STRING( pev->model ), Vector( -16, -16, 0 ), Vector( 16, 16, 72 ) ); } }; @@ -255,7 +255,7 @@ void CCyclerSprite::Spawn( void ) m_animate = 1; m_lastTime = gpGlobals->time; - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); m_maxFrame = (float)MODEL_FRAMES( pev->modelindex ) - 1; @@ -314,7 +314,7 @@ void CWeaponCycler::Spawn() pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_NONE; - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); m_iszModel = pev->model; m_iModel = pev->modelindex; @@ -401,7 +401,7 @@ void CWreckage::Spawn( void ) if( pev->model ) { - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); } // pev->scale = 5.0; @@ -412,7 +412,7 @@ void CWreckage::Spawn( void ) void CWreckage::Precache() { if( pev->model ) - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); } void CWreckage::Think( void ) diff --git a/dlls/islave.cpp b/dlls/islave.cpp index 51def5d3..b516c09b 100644 --- a/dlls/islave.cpp +++ b/dlls/islave.cpp @@ -544,16 +544,16 @@ void CISlave::Precache() PRECACHE_SOUND( "weapons/cbar_miss1.wav" ); for( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackHitSounds[i] ); + PRECACHE_SOUND( pAttackHitSounds[i] ); for( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackMissSounds[i] ); + PRECACHE_SOUND( pAttackMissSounds[i] ); for( i = 0; i < ARRAYSIZE( pPainSounds ); i++ ) - PRECACHE_SOUND((char *)pPainSounds[i] ); + PRECACHE_SOUND( pPainSounds[i] ); for( i = 0; i < ARRAYSIZE( pDeathSounds ); i++ ) - PRECACHE_SOUND( (char *)pDeathSounds[i] ); + PRECACHE_SOUND( pDeathSounds[i] ); UTIL_PrecacheOther( "test_effect" ); } diff --git a/dlls/leech.cpp b/dlls/leech.cpp index dccffcf4..1d64eae1 100644 --- a/dlls/leech.cpp +++ b/dlls/leech.cpp @@ -277,9 +277,9 @@ void CLeech::Precache( void ) PRECACHE_MODEL( "models/leech.mdl" ); for( i = 0; i < ARRAYSIZE( pAttackSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackSounds[i] ); + PRECACHE_SOUND( pAttackSounds[i] ); for( i = 0; i < ARRAYSIZE( pAlertSounds ); i++ ) - PRECACHE_SOUND( (char *)pAlertSounds[i] ); + PRECACHE_SOUND( pAlertSounds[i] ); } int CLeech::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index a898158f..5e06f909 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -92,7 +92,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() if( IS_DEDICATED_SERVER() ) { // dedicated server - /*char *servercfgfile = (char *)CVAR_GET_STRING( "servercfgfile" ); + /*const char *servercfgfile = CVAR_GET_STRING( "servercfgfile" ); if( servercfgfile && servercfgfile[0] ) { @@ -108,7 +108,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() else { // listen server - char *lservercfgfile = (char *)CVAR_GET_STRING( "lservercfgfile" ); + const char *lservercfgfile = CVAR_GET_STRING( "lservercfgfile" ); if( lservercfgfile && lservercfgfile[0] ) { @@ -1214,7 +1214,7 @@ COM_Parse Parse a token out of a string ============== */ -char *COM_Parse( char *data ) +const char *COM_Parse( const char *data ) { int c; int len; @@ -1290,9 +1290,9 @@ COM_TokenWaiting Returns 1 if additional data is waiting to be processed on this line ============== */ -int COM_TokenWaiting( char *buffer ) +int COM_TokenWaiting( const char *buffer ) { - char *p; + const char *p; p = buffer; while( *p && *p!='\n') @@ -1313,12 +1313,12 @@ ReloadMapCycleFile Parses mapcycle.txt file into mapcycle_t structure ============== */ -int ReloadMapCycleFile( char *filename, mapcycle_t *cycle ) +int ReloadMapCycleFile( const char *filename, mapcycle_t *cycle ) { char szMap[32]; int length; - char *pFileList; - char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( filename, &length ); + const char *pFileList; + const char *aFileList = pFileList = (const char *)LOAD_FILE_FOR_ME( filename, &length ); int hasbuffer; mapcycle_item_s *item, *newlist = NULL, *next; @@ -1396,7 +1396,7 @@ int ReloadMapCycleFile( char *filename, mapcycle_t *cycle ) } } - FREE_FILE( aFileList ); + FREE_FILE( (void*)aFileList ); } // Fixup circular list pointer @@ -1532,7 +1532,7 @@ void CHalfLifeMultiplay::ChangeLevel( void ) BOOL do_cycle = TRUE; // find the map to change to - char *mapcfile = (char*)CVAR_GET_STRING( "mapcyclefile" ); + const char *mapcfile = CVAR_GET_STRING( "mapcyclefile" ); ASSERT( mapcfile != NULL ); szCommands[0] = '\0'; @@ -1650,8 +1650,8 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client ) { // read from the MOTD.txt file int length, char_count = 0; - char *pFileList; - char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( (char *)CVAR_GET_STRING( "motdfile" ), &length ); + const char *pFileList; + const char *aFileList = pFileList = (const char*)LOAD_FILE_FOR_ME( CVAR_GET_STRING( "motdfile" ), &length ); // send the server name MESSAGE_BEGIN( MSG_ONE, gmsgServerName, NULL, client ); @@ -1679,7 +1679,7 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client ) if( char_count < MAX_MOTD_LENGTH ) pFileList = aFileList + char_count; else - *pFileList = 0; + pFileList = 0; MESSAGE_BEGIN( MSG_ONE, gmsgMOTD, NULL, client ); WRITE_BYTE( *pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come @@ -1687,5 +1687,5 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client ) MESSAGE_END(); } - FREE_FILE( aFileList ); + FREE_FILE( (void*)aFileList ); } diff --git a/dlls/nodes.cpp b/dlls/nodes.cpp index 68a1c267..b94f894b 100644 --- a/dlls/nodes.cpp +++ b/dlls/nodes.cpp @@ -2108,7 +2108,7 @@ void CTestHull::BuildNodeGraph( void ) WorldGraph.ComputeStaticRoutingTables(); // save the node graph for this level - WorldGraph.FSaveGraph( (char *)STRING( gpGlobals->mapname ) ); + WorldGraph.FSaveGraph( STRING( gpGlobals->mapname ) ); ALERT( at_console, "Done.\n" ); } @@ -2363,7 +2363,7 @@ void CQueuePriority::Heap_SiftUp( void ) // will be loaded. If file cannot be loaded, the node tree // will be created and saved to disk. //========================================================= -int CGraph::FLoadGraph( char *szMapName ) +int CGraph::FLoadGraph( const char *szMapName ) { char szFilename[MAX_PATH]; int iVersion; @@ -2542,7 +2542,7 @@ NoMemory: // CGraph - FSaveGraph - It's not rocket science. // this WILL overwrite existing files. //========================================================= -int CGraph::FSaveGraph( char *szMapName ) +int CGraph::FSaveGraph( const char *szMapName ) { int iVersion = GRAPH_VERSION; char szFilename[MAX_PATH]; @@ -2674,7 +2674,7 @@ int CGraph::FSetGraphPointers( void ) // though. ( I now suspect that we are getting GMT back from // these functions and must compensate for local time ) (sjb) //========================================================= -int CGraph::CheckNODFile( char *szMapName ) +int CGraph::CheckNODFile( const char *szMapName ) { int retValue; diff --git a/dlls/nodes.h b/dlls/nodes.h index 29440025..49036a39 100644 --- a/dlls/nodes.h +++ b/dlls/nodes.h @@ -182,9 +182,9 @@ public: void InitGraph( void ); int AllocNodes ( void ); - int CheckNODFile(char *szMapName); - int FLoadGraph(char *szMapName); - int FSaveGraph(char *szMapName); + int CheckNODFile(const char *szMapName); + int FLoadGraph(const char *szMapName); + int FSaveGraph(const char *szMapName); int FSetGraphPointers(void); void CheckNode(Vector vecOrigin, int iNode); diff --git a/dlls/plats.cpp b/dlls/plats.cpp index 3034fd93..1e6de4bf 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -416,7 +416,7 @@ void CFuncPlat::PlatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE void CFuncPlat::GoDown( void ) { if( pev->noiseMovement ) - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); ASSERT( m_toggle_state == TS_AT_TOP || m_toggle_state == TS_GOING_UP ); m_toggle_state = TS_GOING_DOWN; @@ -430,10 +430,10 @@ void CFuncPlat::GoDown( void ) void CFuncPlat::HitBottom( void ) { if( pev->noiseMovement ) - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMovement ) ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMovement ) ); if( pev->noiseStopMoving ) - EMIT_SOUND( ENT( pev ), CHAN_WEAPON, (char*)STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_WEAPON, STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); ASSERT( m_toggle_state == TS_GOING_DOWN ); m_toggle_state = TS_AT_BOTTOM; @@ -445,7 +445,7 @@ void CFuncPlat::HitBottom( void ) void CFuncPlat::GoUp( void ) { if( pev->noiseMovement ) - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); ASSERT( m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN ); m_toggle_state = TS_GOING_UP; @@ -459,10 +459,10 @@ void CFuncPlat::GoUp( void ) void CFuncPlat::HitTop( void ) { if( pev->noiseMovement ) - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMovement ) ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMovement ) ); if( pev->noiseStopMoving ) - EMIT_SOUND( ENT( pev ), CHAN_WEAPON, (char*)STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_WEAPON, STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); ASSERT( m_toggle_state == TS_GOING_UP ); m_toggle_state = TS_AT_TOP; @@ -482,7 +482,7 @@ void CFuncPlat::Blocked( CBaseEntity *pOther ) pOther->TakeDamage( pev, pev, 1, DMG_CRUSH ); if( pev->noiseMovement ) - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMovement ) ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMovement ) ); // Send the platform back where it came from ASSERT( m_toggle_state == TS_GOING_UP || m_toggle_state == TS_GOING_DOWN ); @@ -670,7 +670,7 @@ void CFuncTrain::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us pev->nextthink = 0; pev->velocity = g_vecZero; if( pev->noiseStopMoving ) - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); } } @@ -691,9 +691,9 @@ void CFuncTrain::Wait( void ) // clear the sound channel. if( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING( pev->noiseMovement ) ); + STOP_SOUND( edict(), CHAN_STATIC, STRING( pev->noiseMovement ) ); if( pev->noiseStopMoving ) - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); pev->nextthink = 0; return; } @@ -704,9 +704,9 @@ void CFuncTrain::Wait( void ) // -1 wait will wait forever! pev->nextthink = pev->ltime + m_flWait; if( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING( pev->noiseMovement ) ); + STOP_SOUND( edict(), CHAN_STATIC, STRING( pev->noiseMovement ) ); if( pev->noiseStopMoving ) - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); SetThink( &CFuncTrain::Next ); } else @@ -728,10 +728,10 @@ void CFuncTrain::Next( void ) if( !pTarg ) { if( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING( pev->noiseMovement ) ); + STOP_SOUND( edict(), CHAN_STATIC, STRING( pev->noiseMovement ) ); // Play stop sound if( pev->noiseStopMoving ) - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); return; } @@ -767,8 +767,8 @@ void CFuncTrain::Next( void ) // this is not a hack or temporary fix, this is how things should be. (sjb). if( pev->noiseMovement ) { - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING( pev->noiseMovement ) ); - EMIT_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); + STOP_SOUND( edict(), CHAN_STATIC, STRING( pev->noiseMovement ) ); + EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); } ClearBits( pev->effects, EF_NOINTERP ); @@ -1061,7 +1061,7 @@ void CFuncTrackTrain::StopSound( void ) PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 1, 0 ); /* - STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noise ) ); + STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noise ) ); */ EMIT_SOUND_DYN( ENT( pev ), CHAN_ITEM, "plats/ttrain_brake1.wav", m_flVolume, ATTN_NORM, 0, 100 ); } @@ -1085,14 +1085,14 @@ void CFuncTrackTrain::UpdateSound( void ) { // play startup sound for train EMIT_SOUND_DYN( ENT( pev ), CHAN_ITEM, "plats/ttrain_start1.wav", m_flVolume, ATTN_NORM, 0, 100 ); - EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noise ), m_flVolume, ATTN_NORM, 0, (int)flpitch ); + EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, STRING( pev->noise ), m_flVolume, ATTN_NORM, 0, (int)flpitch ); m_soundPlaying = 1; } else { /* // update pitch - EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noise ), m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, (int)flpitch ); + EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, STRING( pev->noise ), m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, (int)flpitch ); */ // volume 0.0 - 1.0 - 6 bits // m_sounds 3 bits @@ -1322,7 +1322,7 @@ BOOL CFuncTrackTrain::OnControls( entvars_t *pevTest ) void CFuncTrackTrain::Find( void ) { - m_ppath = CPathTrack::Instance(FIND_ENTITY_BY_TARGETNAME( NULL, STRING( pev->target ) ) ); + m_ppath = CPathTrack::Instance( FIND_ENTITY_BY_TARGETNAME( NULL, STRING( pev->target ) ) ); if( !m_ppath ) return; diff --git a/dlls/prop.cpp b/dlls/prop.cpp index c6c4017e..7f7dba48 100644 --- a/dlls/prop.cpp +++ b/dlls/prop.cpp @@ -248,7 +248,7 @@ void CProp::MaterialSoundPrecache( Materials precacheMaterial ) for( i = 0; i < soundCount; i++ ) { - PRECACHE_SOUND( (char *)pSoundList[i] ); + PRECACHE_SOUND( pSoundList[i] ); } } @@ -327,8 +327,8 @@ void CProp::Precache( void ) if( m_iszGibModel ) pGibName = STRING( m_iszGibModel ); - m_idShard = PRECACHE_MODEL( (char *)pGibName ); - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + m_idShard = PRECACHE_MODEL( pGibName ); + PRECACHE_MODEL( STRING( pev->model ) ); } void CProp::DamageSound( void ) diff --git a/dlls/scripted.cpp b/dlls/scripted.cpp index da9708d1..678502f6 100644 --- a/dlls/scripted.cpp +++ b/dlls/scripted.cpp @@ -712,7 +712,7 @@ void CCineMonster::DelayStart( int state ) else { pTarget->m_iDelay--; - if (pTarget->m_iDelay <= 0) + if( pTarget->m_iDelay <= 0 ) pTarget->m_startTime = gpGlobals->time + 0.05; } } @@ -1177,7 +1177,7 @@ void CFurniture::Die( void ) //========================================================= void CFurniture::Spawn() { - PRECACHE_MODEL( (char *)STRING( pev->model ) ); + PRECACHE_MODEL( STRING( pev->model ) ); SET_MODEL( ENT( pev ), STRING( pev->model ) ); pev->movetype = MOVETYPE_NONE; diff --git a/dlls/sound.cpp b/dlls/sound.cpp index f6110a8d..85b9f71d 100644 --- a/dlls/sound.cpp +++ b/dlls/sound.cpp @@ -182,7 +182,7 @@ void CAmbientGeneric::Spawn( void ) m_flAttenuation = ATTN_STATIC; } - char* szSoundFile = (char*)STRING( pev->message ); + const char *szSoundFile = STRING( pev->message ); if( FStringNull( pev->message ) || strlen( szSoundFile ) < 1 ) { @@ -216,7 +216,7 @@ void CAmbientGeneric::Spawn( void ) void CAmbientGeneric::Precache( void ) { - char* szSoundFile = (char*)STRING( pev->message ); + const char *szSoundFile = STRING( pev->message ); if( !FStringNull( pev->message ) && strlen( szSoundFile ) > 1 ) { @@ -248,7 +248,7 @@ void CAmbientGeneric::Precache( void ) // with lfo if active. void CAmbientGeneric::RampThink( void ) { - char* szSoundFile = (char*) STRING(pev->message); + const char *szSoundFile = STRING( pev->message ); int pitch = m_dpv.pitch; int vol = m_dpv.vol; int flags = 0; @@ -533,7 +533,7 @@ void CAmbientGeneric::InitModulationParms( void ) // void CAmbientGeneric::ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - char* szSoundFile = (char*)STRING( pev->message ); + const char *szSoundFile = STRING( pev->message ); float fraction; if( useType != USE_TOGGLE ) diff --git a/dlls/stats.cpp b/dlls/stats.cpp index 9b21f792..1df298b2 100644 --- a/dlls/stats.cpp +++ b/dlls/stats.cpp @@ -48,7 +48,7 @@ float AmmoDamage( const char *pName ) return 0; } -void UpdateStatsFile( float dataTime, char *pMapname, float health, float ammo, int skillLevel ) +void UpdateStatsFile( float dataTime, const char *pMapname, float health, float ammo, int skillLevel ) { FILE *fp; @@ -136,7 +136,7 @@ void UpdateStats( CBasePlayer *pPlayer ) } else if( ( gStats.nextOutputTime != 0 && gStats.nextOutputTime < gStats.gameTime ) || forceWrite ) { - UpdateStatsFile( gStats.dataTime, (char *)STRING( gpGlobals->mapname ), health, ammo, (int)CVAR_GET_FLOAT( "skill" ) ); + UpdateStatsFile( gStats.dataTime, STRING( gpGlobals->mapname ), health, ammo, (int)CVAR_GET_FLOAT( "skill" ) ); gStats.lastAmmo = ammo; gStats.lastHealth = health; diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index 57d8d031..8171a195 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -527,7 +527,7 @@ void CBaseTrigger::InitTrigger() SetMovedir( pev ); pev->solid = SOLID_TRIGGER; pev->movetype = MOVETYPE_NONE; - SET_MODEL(ENT(pev), STRING( pev->model ) ); // set size and link into world + SET_MODEL( ENT( pev ), STRING( pev->model ) ); // set size and link into world if( CVAR_GET_FLOAT( "showtriggers" ) == 0 ) SetBits( pev->effects, EF_NODRAW ); } @@ -1135,7 +1135,7 @@ void CBaseTrigger::ActivateMultiTrigger( CBaseEntity *pActivator ) } if( !FStringNull( pev->noise ) ) - EMIT_SOUND( ENT( pev ), CHAN_VOICE, (char*)STRING( pev->noise ), 1, ATTN_NORM ); + EMIT_SOUND( ENT( pev ), CHAN_VOICE, STRING( pev->noise ), 1, ATTN_NORM ); // don't trigger again until reset // pev->takedamage = DAMAGE_NO; @@ -1264,7 +1264,7 @@ void CTriggerVolume::Spawn( void ) { pev->solid = SOLID_NOT; pev->movetype = MOVETYPE_NONE; - SET_MODEL( ENT(pev), STRING( pev->model ) ); // set size and link into world + SET_MODEL( ENT( pev ), STRING( pev->model ) ); // set size and link into world pev->model = 0; pev->modelindex = 0; } @@ -1338,7 +1338,7 @@ TYPEDESCRIPTION CChangeLevel::m_SaveData[] = DEFINE_FIELD( CChangeLevel, m_changeTargetDelay, FIELD_FLOAT ), }; -IMPLEMENT_SAVERESTORE(CChangeLevel,CBaseTrigger) +IMPLEMENT_SAVERESTORE( CChangeLevel, CBaseTrigger ) // // Cache user-entity-field values until spawn is called. diff --git a/dlls/util.cpp b/dlls/util.cpp index bca89948..68ba30cd 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1052,7 +1052,7 @@ Vector UTIL_GetAimVector( edict_t *pent, float flSpeed ) return tmp; } -int UTIL_IsMasterTriggered(string_t sMaster, CBaseEntity *pActivator) +int UTIL_IsMasterTriggered( string_t sMaster, CBaseEntity *pActivator ) { if( sMaster ) { @@ -1340,7 +1340,7 @@ void UTIL_StringToVector( float *pVector, const char *pString ) while( *pstr && *pstr != ' ' ) pstr++; - if( !(*pstr) ) + if( !( *pstr ) ) break; pstr++; pfront = pstr; @@ -1858,7 +1858,7 @@ void CSave::WriteString( const char *pname, const int *stringId, int count ) #if 0 if( count != 1 ) ALERT( at_error, "No string arrays!\n" ); - WriteString( pname, (char *)STRING( *stringId ) ); + WriteString( pname, STRING( *stringId ) ); #endif size = 0; for( i = 0; i < count; i++ ) @@ -2209,9 +2209,9 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou if( !FStringNull( string ) && m_precache ) { if( pTest->fieldType == FIELD_MODELNAME ) - PRECACHE_MODEL( (char *)STRING( string ) ); + PRECACHE_MODEL( STRING( string ) ); else if( pTest->fieldType == FIELD_SOUNDNAME ) - PRECACHE_SOUND( (char *)STRING( string ) ); + PRECACHE_SOUND( STRING( string ) ); } } break; diff --git a/dlls/util.h b/dlls/util.h index c13271b0..2ffe536e 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -542,7 +542,7 @@ void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg); void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); #define PRECACHE_SOUND_ARRAY( a ) \ - { for (int i = 0; i < (int)ARRAYSIZE( a ); i++ ) PRECACHE_SOUND((char *) a [i]); } + { for (int i = 0; i < (int)ARRAYSIZE( a ); i++ ) PRECACHE_SOUND( a[i] ); } #define EMIT_SOUND_ARRAY_DYN( chan, array ) \ EMIT_SOUND_DYN ( ENT(pev), chan , array [ RANDOM_LONG(0,ARRAYSIZE( array )-1) ], 1.0, ATTN_NORM, 0, RANDOM_LONG(95,105) ); diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 06bb1796..a1205f27 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -367,7 +367,7 @@ void W_Precache( void ) g_sModelIndexBloodSpray = PRECACHE_MODEL( "sprites/bloodspray.spr" ); // initial blood g_sModelIndexBloodDrop = PRECACHE_MODEL( "sprites/blood.spr" ); // splattered blood - g_sModelIndexLaser = PRECACHE_MODEL( (char *)g_pModelNameLaser ); + g_sModelIndexLaser = PRECACHE_MODEL( g_pModelNameLaser ); g_sModelIndexLaserDot = PRECACHE_MODEL( "sprites/laserdot.spr" ); // used by explosions @@ -535,7 +535,7 @@ CBaseEntity* CBasePlayerItem::Respawn( void ) { // make a copy of this weapon that is invisible and inaccessible to players (no touch function). The weapon spawn/respawn code // will decide when to make the weapon visible and touchable. - CBaseEntity *pNewWeapon = CBaseEntity::Create( (char *)STRING( pev->classname ), g_pGameRules->VecWeaponRespawnSpot( this ), pev->angles, pev->owner ); + CBaseEntity *pNewWeapon = CBaseEntity::Create( STRING( pev->classname ), g_pGameRules->VecWeaponRespawnSpot( this ), pev->angles, pev->owner ); if( pNewWeapon ) { @@ -1297,7 +1297,7 @@ void CWeaponBox::Touch( CBaseEntity *pOther ) if( !FStringNull( m_rgiszAmmo[i] ) ) { // there's some ammo of this type. - pPlayer->GiveAmmo( m_rgAmmo[i], (char *)STRING( m_rgiszAmmo[i] ), MaxAmmoCarry( m_rgiszAmmo[i] ) ); + pPlayer->GiveAmmo( m_rgAmmo[i], STRING( m_rgiszAmmo[i] ), MaxAmmoCarry( m_rgiszAmmo[i] ) ); //ALERT( at_console, "Gave %d rounds of %s\n", m_rgAmmo[i], STRING( m_rgiszAmmo[i] ) ); @@ -1407,7 +1407,7 @@ BOOL CWeaponBox::PackAmmo( int iszName, int iCount ) if( iMaxCarry != -1 && iCount > 0 ) { //ALERT( at_console, "Packed %d rounds of %s\n", iCount, STRING( iszName ) ); - GiveAmmo( iCount, (char *)STRING( iszName ), iMaxCarry ); + GiveAmmo( iCount, STRING( iszName ), iMaxCarry ); return TRUE; } diff --git a/dlls/world.cpp b/dlls/world.cpp index 1cc645c9..3b9a1f1e 100644 --- a/dlls/world.cpp +++ b/dlls/world.cpp @@ -592,7 +592,7 @@ void CWorld::Precache( void ) WorldGraph.InitGraph(); // make sure the .NOD file is newer than the .BSP file. - if( !WorldGraph.CheckNODFile( ( char * )STRING( gpGlobals->mapname ) ) ) + if( !WorldGraph.CheckNODFile( STRING( gpGlobals->mapname ) ) ) { // NOD file is not present, or is older than the BSP file. WorldGraph.AllocNodes(); @@ -600,7 +600,7 @@ void CWorld::Precache( void ) else { // Load the node graph for this level - if( !WorldGraph.FLoadGraph ( (char *)STRING( gpGlobals->mapname ) ) ) + if( !WorldGraph.FLoadGraph( STRING( gpGlobals->mapname ) ) ) { // couldn't load, so alloc and prepare to build a graph. ALERT( at_console, "*Error opening .NOD file\n" ); diff --git a/dlls/xen.cpp b/dlls/xen.cpp index 4e9e1685..1d86beb3 100644 --- a/dlls/xen.cpp +++ b/dlls/xen.cpp @@ -444,9 +444,9 @@ CXenHull *CXenHull::CreateHull( CBaseEntity *source, const Vector &mins, const V CXenHull *pHull = GetClassPtr( (CXenHull *)NULL ); UTIL_SetOrigin( pHull->pev, source->pev->origin + offset ); - SET_MODEL( pHull->edict(), STRING(source->pev->model) ); + SET_MODEL( pHull->edict(), STRING( source->pev->model ) ); pHull->pev->solid = SOLID_BBOX; - pHull->pev->classname = MAKE_STRING("xen_hull"); + pHull->pev->classname = MAKE_STRING( "xen_hull" ); pHull->pev->movetype = MOVETYPE_NONE; pHull->pev->owner = source->edict(); UTIL_SetSize( pHull->pev, mins, maxs ); @@ -527,7 +527,7 @@ const char *CXenSpore::pModelNames[] = void CXenSpore::Precache( void ) { - PRECACHE_MODEL( (char *)pModelNames[pev->skin] ); + PRECACHE_MODEL( pModelNames[pev->skin] ); } void CXenSpore::Touch( CBaseEntity *pOther ) diff --git a/dlls/zombie.cpp b/dlls/zombie.cpp index 2611f881..96f032e6 100644 --- a/dlls/zombie.cpp +++ b/dlls/zombie.cpp @@ -266,7 +266,7 @@ void CZombie::Spawn() { Precache(); - SET_MODEL( ENT(pev), "models/zombie.mdl" ); + SET_MODEL( ENT( pev ), "models/zombie.mdl" ); UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX ); pev->solid = SOLID_SLIDEBOX; @@ -291,22 +291,22 @@ void CZombie::Precache() PRECACHE_MODEL( "models/zombie.mdl" ); for( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackHitSounds[i] ); + PRECACHE_SOUND( pAttackHitSounds[i] ); for( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackMissSounds[i] ); + PRECACHE_SOUND( pAttackMissSounds[i] ); for( i = 0; i < ARRAYSIZE( pAttackSounds ); i++ ) - PRECACHE_SOUND( (char *)pAttackSounds[i] ); + PRECACHE_SOUND( pAttackSounds[i] ); for( i = 0; i < ARRAYSIZE( pIdleSounds ); i++ ) - PRECACHE_SOUND( (char *)pIdleSounds[i] ); + PRECACHE_SOUND( pIdleSounds[i] ); for( i = 0; i < ARRAYSIZE( pAlertSounds ); i++ ) - PRECACHE_SOUND( (char *)pAlertSounds[i] ); + PRECACHE_SOUND( pAlertSounds[i] ); for( i = 0; i < ARRAYSIZE( pPainSounds ); i++ ) - PRECACHE_SOUND( (char *)pPainSounds[i] ); + PRECACHE_SOUND( pPainSounds[i] ); } //========================================================= From 4150b464a047d87f398c8a9838a6a27fa3646418 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 24 Jul 2017 16:38:38 +0500 Subject: [PATCH 102/211] Improve spectator. --- dlls/client.cpp | 28 +++++++++++++++++++--------- dlls/observer.cpp | 23 +++++++++++++++++++++++ dlls/player.h | 1 + 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/dlls/client.cpp b/dlls/client.cpp index 569b1a53..32b6bebd 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -556,20 +556,30 @@ void ClientCommand( edict_t *pEntity ) } else if( FStrEq( pcmd, "spectate" ) ) // clients wants to become a spectator { - // always allow proxies to become a spectator - if( ( pev->flags & FL_PROXY ) || allow_spectators.value ) + CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev ); + if( !pPlayer->IsObserver() ) { - CBasePlayer *pPlayer = GetClassPtr( (CBasePlayer *)pev ); + // always allow proxies to become a spectator + if( ( pev->flags & FL_PROXY ) || allow_spectators.value ) + { + edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer ); + pPlayer->StartObserver( pev->origin, VARS( pentSpawnSpot )->angles ); - edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer ); - pPlayer->StartObserver( pev->origin, VARS( pentSpawnSpot )->angles ); - - // notify other clients of player switching to spectator mode - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s switched to spectator mode\n", + // notify other clients of player switching to spectator mode + UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s switched to spectator mode\n", ( pev->netname && ( STRING( pev->netname ) )[0] != 0 ) ? STRING( pev->netname ) : "unconnected" ) ); + } + else + ClientPrint( pev, HUD_PRINTCONSOLE, "Spectator mode is disabled.\n" ); } else - ClientPrint( pev, HUD_PRINTCONSOLE, "Spectator mode is disabled.\n" ); + { + pPlayer->StopObserver(); + + // notify other clients of player left spectators + UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s has left spectator mode\n", + ( pev->netname && ( STRING( pev->netname ) )[0] != 0 ) ? STRING( pev->netname ) : "unconnected" ) ); + } } else if( FStrEq( pcmd, "specmode" ) ) // new spectator mode { diff --git a/dlls/observer.cpp b/dlls/observer.cpp index f3fc54a0..22fa3818 100644 --- a/dlls/observer.cpp +++ b/dlls/observer.cpp @@ -24,6 +24,10 @@ extern int gmsgCurWeapon; extern int gmsgSetFOV; +extern int gmsgTeamInfo; + +extern int g_teamplay; + // Find the next client in the game for this player to spectate void CBasePlayer::Observer_FindNextPlayer( bool bReverse ) { @@ -266,3 +270,22 @@ void CBasePlayer::Observer_SetMode( int iMode ) m_iObserverLastMode = iMode; } + +void CBasePlayer::StopObserver() +{ + // Turn off spectator + pev->iuser1 = pev->iuser2 = 0; + m_iHideHUD = 0; + + GetClassPtr( (CBasePlayer *)pev )->Spawn(); + pev->nextthink = -1; + + // Update Team Status + MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); + WRITE_BYTE( ENTINDEX( edict() ) ); // index number of primary entity + if( g_teamplay ) + WRITE_STRING( TeamID() ); + else + WRITE_STRING( "Players" ); + MESSAGE_END(); +} diff --git a/dlls/player.h b/dlls/player.h index 1c17556c..54e7fa85 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -255,6 +255,7 @@ public: void StartDeathCam( void ); void StartObserver( Vector vecPosition, Vector vecViewAngle ); + void StopObserver(); void AddPoints( int score, BOOL bAllowNegativeScore ); void AddPointsToTeam( int score, BOOL bAllowNegativeScore ); From aaf81c770994d179c43b39e4233299752dec7f44 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 24 Jul 2017 16:56:43 +0500 Subject: [PATCH 103/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/ef7cecf654ccf7716a5646ff9498928905a266dc --- pm_shared/pm_math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm_shared/pm_math.c b/pm_shared/pm_math.c index 5bbe0068..4bb4b93f 100644 --- a/pm_shared/pm_math.c +++ b/pm_shared/pm_math.c @@ -239,7 +239,7 @@ float AngleBetweenVectors( const vec3_t v1, const vec3_t v2 ) if( !l1 || !l2 ) return 0.0f; - angle = acos( DotProduct( v1, v2 ) ) / ( l1 * l2 ); + angle = acos( DotProduct( v1, v2 ) / ( l1 * l2 ) ); angle = ( angle * 180.0f ) / M_PI; return angle; From 96b1f4c58e8d8be9c1f743275b3ab562e50111ea Mon Sep 17 00:00:00 2001 From: mittorn Date: Sun, 30 Jul 2017 12:30:47 +0300 Subject: [PATCH 104/211] Fix wrong -std=c99 --- cl_dll/Android.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/cl_dll/Android.mk b/cl_dll/Android.mk index ecbae657..a79b6363 100755 --- a/cl_dll/Android.mk +++ b/cl_dll/Android.mk @@ -13,7 +13,6 @@ LOCAL_MODULE := client #else APP_PLATFORM := android-8 #endif -LOCAL_CONLYFLAGS += -std=c99 include $(XASH3D_CONFIG) From f14d7cc552dadde3756edddbf72a04251b620c9c Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 24 Jul 2017 23:07:59 +0500 Subject: [PATCH 105/211] A little fix. --- dlls/multiplay_gamerules.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 5e06f909..8d089696 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -1682,7 +1682,7 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client ) pFileList = 0; MESSAGE_BEGIN( MSG_ONE, gmsgMOTD, NULL, client ); - WRITE_BYTE( *pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come + WRITE_BYTE( pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come WRITE_STRING( chunk ); MESSAGE_END(); } From e3f953064dfe57f407d5129b432705d5d184af02 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 25 Jul 2017 13:24:06 +0500 Subject: [PATCH 106/211] Remove unneeded macros. --- dlls/enginecallback.h | 4 ---- engine/custom.h | 5 ----- engine/edict.h | 4 ---- engine/progdefs.h | 5 ----- pm_shared/pm_debug.h | 4 ---- pm_shared/pm_defs.h | 5 ----- pm_shared/pm_info.h | 4 ---- pm_shared/pm_shared.h | 4 ---- 8 files changed, 35 deletions(-) diff --git a/dlls/enginecallback.h b/dlls/enginecallback.h index 9bef0d48..a9e37c26 100644 --- a/dlls/enginecallback.h +++ b/dlls/enginecallback.h @@ -15,11 +15,7 @@ #ifndef ENGINECALLBACK_H #define ENGINECALLBACK_H -#ifdef _WIN32 -#ifndef __MINGW32__ #pragma once -#endif /* not __MINGW32__ */ -#endif #include "event_flags.h" diff --git a/engine/custom.h b/engine/custom.h index 8f644e00..30ee8d53 100644 --- a/engine/custom.h +++ b/engine/custom.h @@ -12,15 +12,10 @@ * without written permission from Valve LLC. * ****/ - #ifndef CUSTOM_H #define CUSTOM_H -#ifdef _WIN32 -#ifndef __MINGW32__ #pragma once -#endif /* not __MINGW32__ */ -#endif #include "const.h" diff --git a/engine/edict.h b/engine/edict.h index e89b6926..3994c705 100644 --- a/engine/edict.h +++ b/engine/edict.h @@ -16,11 +16,7 @@ #ifndef EDICT_H #define EDICT_H -#ifdef _WIN32 -#ifndef __MINGW32__ #pragma once -#endif /* not __MINGW32__ */ -#endif #define MAX_ENT_LEAFS 48 diff --git a/engine/progdefs.h b/engine/progdefs.h index cdbcc006..56d904b1 100644 --- a/engine/progdefs.h +++ b/engine/progdefs.h @@ -12,15 +12,10 @@ * without written permission from Valve LLC. * ****/ - #ifndef PROGDEFS_H #define PROGDEFS_H -#ifdef _WIN32 -#ifndef __MINGW32__ #pragma once -#endif /* not __MINGW32__ */ -#endif typedef struct { diff --git a/pm_shared/pm_debug.h b/pm_shared/pm_debug.h index cc130598..417c3478 100644 --- a/pm_shared/pm_debug.h +++ b/pm_shared/pm_debug.h @@ -15,11 +15,7 @@ #ifndef PM_DEBUG_H #define PM_DEBUG_H -#ifdef _WIN32 -#ifndef __MINGW32__ #pragma once -#endif /* not __MINGW32__ */ -#endif void PM_ViewEntity( void ); void PM_DrawBBox( vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life ); diff --git a/pm_shared/pm_defs.h b/pm_shared/pm_defs.h index b4c652ba..eddb17b6 100644 --- a/pm_shared/pm_defs.h +++ b/pm_shared/pm_defs.h @@ -12,15 +12,10 @@ * without written permission from Valve LLC. * ****/ - #ifndef PM_DEFS_H #define PM_DEFS_H -#ifdef _WIN32 -#ifndef __MINGW32__ #pragma once -#endif /* not __MINGW32__ */ -#endif #define MAX_PHYSENTS 600 // Must have room for all entities in the world. #define MAX_MOVEENTS 64 diff --git a/pm_shared/pm_info.h b/pm_shared/pm_info.h index d9dbc03d..d75b67fc 100644 --- a/pm_shared/pm_info.h +++ b/pm_shared/pm_info.h @@ -15,11 +15,7 @@ #ifndef PM_INFO_H #define PM_INFO_H -#ifdef _WIN32 -#ifndef __MINGW32__ #pragma once -#endif /* not __MINGW32__ */ -#endif #define MAX_PHYSINFO_STRING 256 #endif//PM_INFO_H diff --git a/pm_shared/pm_shared.h b/pm_shared/pm_shared.h index 1d0e4f38..2fb947a2 100644 --- a/pm_shared/pm_shared.h +++ b/pm_shared/pm_shared.h @@ -16,11 +16,7 @@ #ifndef PM_SHARED_H #define PM_SHARED_H -#ifdef _WIN32 -#ifndef __MINGW32__ #pragma once -#endif /* not __MINGW32__ */ -#endif void PM_Init( struct playermove_s *ppmove ); void PM_Move( struct playermove_s *ppmove, int server ); From 65dc1997f7685b8cb6adc9ac1cb5594ca5f9c623 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Tue, 25 Jul 2017 23:52:50 +0500 Subject: [PATCH 107/211] Fix typo. --- dlls/plats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/plats.cpp b/dlls/plats.cpp index 1e6de4bf..c1220f3c 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -1502,7 +1502,7 @@ void CFuncTrackTrain::Precache( void ) break; } - if( !pszSound ) + if( pszSound ) { PRECACHE_SOUND( pszSound ); pev->noise = MAKE_STRING( pszSound ); From 46ecb7e8eecc446472504f0112cb80fc0b64d4b4 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 9 Oct 2017 19:51:51 +0500 Subject: [PATCH 108/211] Fix shadowing variables. --- cl_dll/ev_hldm.cpp | 16 ++++++++-------- cl_dll/view.cpp | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index d94f9fea..80073b27 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -38,7 +38,7 @@ extern engine_studio_api_t IEngineStudio; -static int tracerCount[32]; +static int g_tracerCount[32]; extern "C" char PM_FindTextureType( char *name ); @@ -546,7 +546,7 @@ void EV_FireGlock2( event_args_t *args ) VectorCopy( forward, vecAiming ); - EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_9MM, 0, &tracerCount[idx - 1], args->fparam1, args->fparam2 ); + EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_9MM, 0, &g_tracerCount[idx - 1], args->fparam1, args->fparam2 ); } //====================== // GLOCK END @@ -602,11 +602,11 @@ void EV_FireShotGunDouble( event_args_t *args ) if( gEngfuncs.GetMaxClients() > 1 ) { - EV_HLDM_FireBullets( idx, forward, right, up, 8, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &tracerCount[idx - 1], 0.17365, 0.04362 ); + EV_HLDM_FireBullets( idx, forward, right, up, 8, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &g_tracerCount[idx - 1], 0.17365, 0.04362 ); } else { - EV_HLDM_FireBullets( idx, forward, right, up, 12, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &tracerCount[idx - 1], 0.08716, 0.08716 ); + EV_HLDM_FireBullets( idx, forward, right, up, 12, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &g_tracerCount[idx - 1], 0.08716, 0.08716 ); } } @@ -654,11 +654,11 @@ void EV_FireShotGunSingle( event_args_t *args ) if( gEngfuncs.GetMaxClients() > 1 ) { - EV_HLDM_FireBullets( idx, forward, right, up, 4, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &tracerCount[idx - 1], 0.08716, 0.04362 ); + EV_HLDM_FireBullets( idx, forward, right, up, 4, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &g_tracerCount[idx - 1], 0.08716, 0.04362 ); } else { - EV_HLDM_FireBullets( idx, forward, right, up, 6, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &tracerCount[idx - 1], 0.08716, 0.08716 ); + EV_HLDM_FireBullets( idx, forward, right, up, 6, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &g_tracerCount[idx - 1], 0.08716, 0.08716 ); } } //====================== @@ -719,11 +719,11 @@ void EV_FireMP5( event_args_t *args ) if( gEngfuncs.GetMaxClients() > 1 ) { - EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_MP5, 2, &tracerCount[idx - 1], args->fparam1, args->fparam2 ); + EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_MP5, 2, &g_tracerCount[idx - 1], args->fparam1, args->fparam2 ); } else { - EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_MP5, 2, &tracerCount[idx - 1], args->fparam1, args->fparam2 ); + EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_MP5, 2, &g_tracerCount[idx - 1], args->fparam1, args->fparam2 ); } } diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index efa4b104..a4abe91c 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -91,7 +91,7 @@ float v_cameraFocusAngle = 35.0f; int v_cameraMode = CAM_MODE_FOCUS; qboolean v_resetCamera = 1; -vec3_t ev_punchangle; +vec3_t g_ev_punchangle; cvar_t *scr_ofsx; cvar_t *scr_ofsy; @@ -630,9 +630,9 @@ void V_CalcNormalRefdef( struct ref_params_s *pparams ) VectorAdd( pparams->viewangles, pparams->punchangle, pparams->viewangles ); // Include client side punch, too - VectorAdd( pparams->viewangles, (float *)&ev_punchangle, pparams->viewangles ); + VectorAdd( pparams->viewangles, (float *)&g_ev_punchangle, pparams->viewangles ); - V_DropPunchAngle( pparams->frametime, (float *)&ev_punchangle ); + V_DropPunchAngle( pparams->frametime, (float *)&g_ev_punchangle ); // smooth out stair step ups #if 1 @@ -1579,7 +1579,7 @@ Client side punch effect */ void V_PunchAxis( int axis, float punch ) { - ev_punchangle[axis] = punch; + g_ev_punchangle[axis] = punch; } /* From e7989d438a4eea04317fc4dd7b79b34c9c18f3d8 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 15 Oct 2017 00:12:26 +0500 Subject: [PATCH 109/211] Fix compatibility with MSVC 6. --- cl_dll/ammo.cpp | 6 +++--- dlls/player.cpp | 2 +- dlls/scientist.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index edc21652..4104acff 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -305,7 +305,7 @@ void CHudAmmo::Reset( void ) gHR.Reset(); //VidInit(); - wrect_t nullrc = {}; + wrect_t nullrc = {0,}; SetCrosshair( 0, nullrc, 0, 0, 0 ); // reset crosshair m_pWeapon = NULL; // reset last weapon } @@ -539,7 +539,7 @@ int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) if( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) { - wrect_t nullrc = {}; + wrect_t nullrc = {0,}; gpActiveSel = NULL; SetCrosshair( 0, nullrc, 0, 0, 0 ); } @@ -559,7 +559,7 @@ int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) // int CHudAmmo::MsgFunc_CurWeapon( const char *pszName, int iSize, void *pbuf ) { - wrect_t nullrc = {}; + wrect_t nullrc = {0,}; int fOnTarget = FALSE; BEGIN_READ( pbuf, iSize ); diff --git a/dlls/player.cpp b/dlls/player.cpp index 38038b36..e5a01bae 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -666,7 +666,7 @@ void CBasePlayer::PackDeadPlayerItems( void ) int iWeaponRules; int iAmmoRules; int i; - CBasePlayerWeapon *rgpPackWeapons[MAX_WEAPONS] = {}; + CBasePlayerWeapon *rgpPackWeapons[MAX_WEAPONS] = {0,}; int iPackAmmo[MAX_AMMO_SLOTS]; int iPW = 0;// index into packweapons array int iPA = 0;// index into packammo array diff --git a/dlls/scientist.cpp b/dlls/scientist.cpp index 7cf9cc4d..7e94b286 100644 --- a/dlls/scientist.cpp +++ b/dlls/scientist.cpp @@ -467,7 +467,7 @@ void CScientist::StartTask( Task_t *pTask ) //The enemy can be null here. - Solokiller //Discovered while testing the barnacle grapple on headcrabs with scientists in view. - if( m_hEnemy && m_hEnemy->IsPlayer() ) + if( m_hEnemy != 0 && m_hEnemy->IsPlayer() ) PlaySentence( "SC_PLFEAR", 5, VOL_NORM, ATTN_NORM ); else PlaySentence( "SC_FEAR", 5, VOL_NORM, ATTN_NORM ); From f78471ad1d562ba0a53a43981fba5a823ca3957f Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 15 Oct 2017 00:57:55 +0500 Subject: [PATCH 110/211] min->Q_min, max->Q_max. --- cl_dll/hl/hl_weapons.cpp | 2 +- dlls/apache.cpp | 8 ++++---- dlls/client.cpp | 8 ++++---- dlls/combat.cpp | 2 +- dlls/effects.cpp | 12 ++++++------ dlls/extdll.h | 8 ++++---- dlls/hassassin.cpp | 4 ++-- dlls/items.cpp | 2 +- dlls/maprules.cpp | 2 +- dlls/monsters.cpp | 2 +- dlls/multiplay_gamerules.cpp | 8 ++++---- dlls/nihilanth.cpp | 4 ++-- dlls/nodes.cpp | 14 +++++++------- dlls/player.cpp | 16 ++++++++-------- dlls/sound.cpp | 2 +- dlls/talkmonster.cpp | 4 ++-- dlls/turret.cpp | 2 +- dlls/util.cpp | 4 ++-- dlls/weapons.cpp | 8 ++++---- 19 files changed, 56 insertions(+), 56 deletions(-) diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 8f8baea7..75161a9e 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -151,7 +151,7 @@ BOOL CBasePlayerWeapon::DefaultReload( int iClipSize, int iAnim, float fDelay, i if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) return FALSE; - int j = min( iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ); + int j = Q_min( iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ); if( j == 0 ) return FALSE; diff --git a/dlls/apache.cpp b/dlls/apache.cpp index aeeea30e..b3cfcf87 100644 --- a/dlls/apache.cpp +++ b/dlls/apache.cpp @@ -804,13 +804,13 @@ BOOL CApache::FireGun() angles.x = angles.x + 360; if( angles.x > m_angGun.x ) - m_angGun.x = min( angles.x, m_angGun.x + 12 ); + m_angGun.x = Q_min( angles.x, m_angGun.x + 12 ); if( angles.x < m_angGun.x ) - m_angGun.x = max( angles.x, m_angGun.x - 12 ); + m_angGun.x = Q_max( angles.x, m_angGun.x - 12 ); if( angles.y > m_angGun.y ) - m_angGun.y = min( angles.y, m_angGun.y + 12 ); + m_angGun.y = Q_min( angles.y, m_angGun.y + 12 ); if( angles.y < m_angGun.y ) - m_angGun.y = max( angles.y, m_angGun.y - 12 ); + m_angGun.y = Q_max( angles.y, m_angGun.y - 12 ); m_angGun.y = SetBoneController( 0, m_angGun.y ); m_angGun.x = SetBoneController( 1, m_angGun.x ); diff --git a/dlls/client.cpp b/dlls/client.cpp index 32b6bebd..578534e3 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -1656,12 +1656,12 @@ int GetWeaponData( struct edict_s *player, struct weapon_data_s *info ) item->m_iId = II.iId; item->m_iClip = gun->m_iClip; - item->m_flTimeWeaponIdle = max( gun->m_flTimeWeaponIdle, -0.001 ); - item->m_flNextPrimaryAttack = max( gun->m_flNextPrimaryAttack, -0.001 ); - item->m_flNextSecondaryAttack = max( gun->m_flNextSecondaryAttack, -0.001 ); + item->m_flTimeWeaponIdle = Q_max( gun->m_flTimeWeaponIdle, -0.001 ); + item->m_flNextPrimaryAttack = Q_max( gun->m_flNextPrimaryAttack, -0.001 ); + item->m_flNextSecondaryAttack = Q_max( gun->m_flNextSecondaryAttack, -0.001 ); item->m_fInReload = gun->m_fInReload; item->m_fInSpecialReload = gun->m_fInSpecialReload; - item->fuser1 = max( gun->pev->fuser1, -0.001 ); + item->fuser1 = Q_max( gun->pev->fuser1, -0.001 ); item->fuser2 = gun->m_flStartThrow; item->fuser3 = gun->m_flReleaseThrow; item->iuser1 = gun->m_chargeReady; diff --git a/dlls/combat.cpp b/dlls/combat.cpp index 35e4ffcf..9f221cc9 100644 --- a/dlls/combat.cpp +++ b/dlls/combat.cpp @@ -727,7 +727,7 @@ void CGib::BounceGibTouch( CBaseEntity *pOther ) float volume; float zvel = fabs( pev->velocity.z ); - volume = 0.8 * min( 1.0, ( (float)zvel ) / 450.0 ); + volume = 0.8 * Q_min( 1.0, ( (float)zvel ) / 450.0 ); CBreakable::MaterialSoundRandom( edict(), (Materials)m_material, volume ); } diff --git a/dlls/effects.cpp b/dlls/effects.cpp index c3216835..15df3bc3 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -280,12 +280,12 @@ void CBeam::RelinkBeam( void ) { const Vector &startPos = GetStartPos(), &endPos = GetEndPos(); - pev->mins.x = min( startPos.x, endPos.x ); - pev->mins.y = min( startPos.y, endPos.y ); - pev->mins.z = min( startPos.z, endPos.z ); - pev->maxs.x = max( startPos.x, endPos.x ); - pev->maxs.y = max( startPos.y, endPos.y ); - pev->maxs.z = max( startPos.z, endPos.z ); + pev->mins.x = Q_min( startPos.x, endPos.x ); + pev->mins.y = Q_min( startPos.y, endPos.y ); + pev->mins.z = Q_min( startPos.z, endPos.z ); + pev->maxs.x = Q_max( startPos.x, endPos.x ); + pev->maxs.y = Q_max( startPos.y, endPos.y ); + pev->maxs.z = Q_max( startPos.z, endPos.z ); pev->mins = pev->mins - pev->origin; pev->maxs = pev->maxs - pev->origin; diff --git a/dlls/extdll.h b/dlls/extdll.h index d9587bae..45c42309 100644 --- a/dlls/extdll.h +++ b/dlls/extdll.h @@ -88,11 +88,11 @@ typedef float vec_t; // needed before including progdefs.h // Shared header between the client DLL and the game DLLs #include "cdll_dll.h" -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) +#ifndef Q_min +#define Q_min(a,b) (((a) < (b)) ? (a) : (b)) #endif -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#ifndef Q_max +#define Q_max(a,b) (((a) > (b)) ? (a) : (b)) #endif #endif //EXTDLL_H diff --git a/dlls/hassassin.cpp b/dlls/hassassin.cpp index ff053595..f51ed4cb 100644 --- a/dlls/hassassin.cpp +++ b/dlls/hassassin.cpp @@ -699,12 +699,12 @@ void CHAssassin::RunAI( void ) EMIT_SOUND( ENT( pev ), CHAN_BODY, "debris/beamstart1.wav", 0.2, ATTN_NORM ); } - pev->renderamt = max( pev->renderamt - 50, m_iTargetRanderamt ); + pev->renderamt = Q_max( pev->renderamt - 50, m_iTargetRanderamt ); pev->rendermode = kRenderTransTexture; } else if( pev->renderamt < m_iTargetRanderamt ) { - pev->renderamt = min( pev->renderamt + 50, m_iTargetRanderamt ); + pev->renderamt = Q_min( pev->renderamt + 50, m_iTargetRanderamt ); if( pev->renderamt == 255 ) pev->rendermode = kRenderNormal; } diff --git a/dlls/items.cpp b/dlls/items.cpp index b0b2aa38..45edeb5e 100644 --- a/dlls/items.cpp +++ b/dlls/items.cpp @@ -227,7 +227,7 @@ class CItemBattery : public CItem char szcharge[64]; pPlayer->pev->armorvalue += gSkillData.batteryCapacity; - pPlayer->pev->armorvalue = min( pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY ); + pPlayer->pev->armorvalue = Q_min( pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY ); EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); diff --git a/dlls/maprules.cpp b/dlls/maprules.cpp index bfec93e2..519f7d2a 100644 --- a/dlls/maprules.cpp +++ b/dlls/maprules.cpp @@ -768,7 +768,7 @@ void CGamePlayerEquip::KeyValue( KeyValueData *pkvd ) m_weaponNames[i] = ALLOC_STRING( tmp ); m_weaponCount[i] = atoi( pkvd->szValue ); - m_weaponCount[i] = max( 1, m_weaponCount[i] ); + m_weaponCount[i] = Q_max( 1, m_weaponCount[i] ); pkvd->fHandled = TRUE; break; } diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index a9796a80..1e1d3de3 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -1959,7 +1959,7 @@ void CBaseMonster::MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, f while( flTotal > 0.001 ) { // don't walk more than 16 units or stairs stop working - flStep = min( 16.0, flTotal ); + flStep = Q_min( 16.0, flTotal ); UTIL_MoveToOrigin( ENT( pev ), m_Route[m_iRouteIndex].vecLocation, flStep, MOVE_NORMAL ); flTotal -= flStep; } diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 8d089696..7922d413 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -1368,15 +1368,15 @@ int ReloadMapCycleFile( const char *filename, mapcycle_t *cycle ) if( s && s[0] ) { item->minplayers = atoi( s ); - item->minplayers = max( item->minplayers, 0 ); - item->minplayers = min( item->minplayers, gpGlobals->maxClients ); + item->minplayers = Q_max( item->minplayers, 0 ); + item->minplayers = Q_min( item->minplayers, gpGlobals->maxClients ); } s = g_engfuncs.pfnInfoKeyValue( szBuffer, "maxplayers" ); if( s && s[0] ) { item->maxplayers = atoi( s ); - item->maxplayers = max( item->maxplayers, 0 ); - item->maxplayers = min( item->maxplayers, gpGlobals->maxClients ); + item->maxplayers = Q_max( item->maxplayers, 0 ); + item->maxplayers = Q_min( item->maxplayers, gpGlobals->maxClients ); } // Remove keys diff --git a/dlls/nihilanth.cpp b/dlls/nihilanth.cpp index 34375a58..1d072db4 100644 --- a/dlls/nihilanth.cpp +++ b/dlls/nihilanth.cpp @@ -478,7 +478,7 @@ void CNihilanth::DyingThink( void ) { if( m_pBall->pev->renderamt > 0 ) { - m_pBall->pev->renderamt = max( 0, m_pBall->pev->renderamt - 2 ); + m_pBall->pev->renderamt = Q_max( 0, m_pBall->pev->renderamt - 2 ); } else { @@ -895,7 +895,7 @@ void CNihilanth::HuntThink( void ) } else { - m_flAdj = min( m_flAdj + 10, 1000 ); + m_flAdj = Q_min( m_flAdj + 10, 1000 ); } } diff --git a/dlls/nodes.cpp b/dlls/nodes.cpp index b94f894b..04705638 100644 --- a/dlls/nodes.cpp +++ b/dlls/nodes.cpp @@ -793,12 +793,12 @@ void inline CalcBounds( int &Lower, int &Upper, int Goal, int Best ) int Temp = 2 * Goal - Best; if( Best > Goal ) { - Lower = max( 0, Temp ); + Lower = Q_max( 0, Temp ); Upper = Best; } else { - Upper = min( 255, Temp ); + Upper = Q_min( 255, Temp ); Lower = Best; } } @@ -962,7 +962,7 @@ int CGraph::FindNearestNode( const Vector &vecOrigin, int afNodeTypes ) } } - for( i = max( m_minY, halfY + 1 ); i <= m_maxY; i++ ) + for( i = Q_max( m_minY, halfY + 1 ); i <= m_maxY; i++ ) { for( j = m_RangeStart[1][i]; j <= m_RangeEnd[1][i]; j++ ) { @@ -987,7 +987,7 @@ int CGraph::FindNearestNode( const Vector &vecOrigin, int afNodeTypes ) } } - for( i = min( m_maxZ, halfZ ); i >= m_minZ; i-- ) + for( i = Q_min( m_maxZ, halfZ ); i >= m_minZ; i-- ) { for( j = m_RangeStart[2][i]; j <= m_RangeEnd[2][i]; j++ ) { @@ -1012,7 +1012,7 @@ int CGraph::FindNearestNode( const Vector &vecOrigin, int afNodeTypes ) } } - for( i = max( m_minX, halfX + 1 ); i <= m_maxX; i++ ) + for( i = Q_max( m_minX, halfX + 1 ); i <= m_maxX; i++ ) { for( j = m_RangeStart[0][i]; j <= m_RangeEnd[0][i]; j++ ) { @@ -1034,7 +1034,7 @@ int CGraph::FindNearestNode( const Vector &vecOrigin, int afNodeTypes ) } } - for( i = min( m_maxY, halfY ); i >= m_minY; i-- ) + for( i = Q_min( m_maxY, halfY ); i >= m_minY; i-- ) { for( j = m_RangeStart[1][i]; j <= m_RangeEnd[1][i]; j++ ) { @@ -1055,7 +1055,7 @@ int CGraph::FindNearestNode( const Vector &vecOrigin, int afNodeTypes ) } } - for( i = max( m_minZ, halfZ + 1 ); i <= m_maxZ; i++ ) + for( i = Q_max( m_minZ, halfZ + 1 ); i <= m_maxZ; i++ ) { for( j = m_RangeStart[2][i]; j <= m_RangeEnd[2][i]; j++ ) { diff --git a/dlls/player.cpp b/dlls/player.cpp index e5a01bae..757f03e4 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -2049,7 +2049,7 @@ void CBasePlayer::CheckTimeBasedDamage() // after the player has been drowning and finally takes a breath if( m_idrowndmg > m_idrownrestored ) { - int idif = min( m_idrowndmg - m_idrownrestored, 10 ); + int idif = Q_min( m_idrowndmg - m_idrownrestored, 10 ); TakeHealth( idif, DMG_GENERIC ); m_idrownrestored += idif; @@ -2606,23 +2606,23 @@ pt_end: if( gun && gun->UseDecrement() ) { - gun->m_flNextPrimaryAttack = max( gun->m_flNextPrimaryAttack - gpGlobals->frametime, -1.0 ); - gun->m_flNextSecondaryAttack = max( gun->m_flNextSecondaryAttack - gpGlobals->frametime, -0.001 ); + gun->m_flNextPrimaryAttack = Q_max( gun->m_flNextPrimaryAttack - gpGlobals->frametime, -1.0 ); + gun->m_flNextSecondaryAttack = Q_max( gun->m_flNextSecondaryAttack - gpGlobals->frametime, -0.001 ); if( gun->m_flTimeWeaponIdle != 1000 ) { - gun->m_flTimeWeaponIdle = max( gun->m_flTimeWeaponIdle - gpGlobals->frametime, -0.001 ); + gun->m_flTimeWeaponIdle = Q_max( gun->m_flTimeWeaponIdle - gpGlobals->frametime, -0.001 ); } if( gun->pev->fuser1 != 1000 ) { - gun->pev->fuser1 = max( gun->pev->fuser1 - gpGlobals->frametime, -0.001 ); + gun->pev->fuser1 = Q_max( gun->pev->fuser1 - gpGlobals->frametime, -0.001 ); } // Only decrement if not flagged as NO_DECREMENT /*if( gun->m_flPumpTime != 1000 ) { - gun->m_flPumpTime = max( gun->m_flPumpTime - gpGlobals->frametime, -0.001 ); + gun->m_flPumpTime = Q_max( gun->m_flPumpTime - gpGlobals->frametime, -0.001 ); }*/ } @@ -3705,7 +3705,7 @@ int CBasePlayer::GiveAmmo( int iCount, const char *szName, int iMax ) if( i < 0 || i >= MAX_AMMO_SLOTS ) return -1; - int iAdd = min( iCount, iMax - m_rgAmmo[i] ); + int iAdd = Q_min( iCount, iMax - m_rgAmmo[i] ); if( iAdd < 1 ) return i; @@ -3826,7 +3826,7 @@ void CBasePlayer::SendAmmoUpdate( void ) // send "Ammo" update message MESSAGE_BEGIN( MSG_ONE, gmsgAmmoX, NULL, pev ); WRITE_BYTE( i ); - WRITE_BYTE( max( min( m_rgAmmo[i], 254 ), 0 ) ); // clamp the value to one byte + WRITE_BYTE( Q_max( Q_min( m_rgAmmo[i], 254 ), 0 ) ); // clamp the value to one byte MESSAGE_END(); } } diff --git a/dlls/sound.cpp b/dlls/sound.cpp index 85b9f71d..31d0b7aa 100644 --- a/dlls/sound.cpp +++ b/dlls/sound.cpp @@ -1567,7 +1567,7 @@ void TEXTURETYPE_Init() continue; // null-terminate name and save in sentences array - j = min( j, CBTEXTURENAMEMAX - 1 + i ); + j = Q_min( j, CBTEXTURENAMEMAX - 1 + i ); buffer[j] = 0; strcpy( &( grgszTextureName[gcTextures++][0] ), &( buffer[i] ) ); } diff --git a/dlls/talkmonster.cpp b/dlls/talkmonster.cpp index 35bf3856..9180f037 100644 --- a/dlls/talkmonster.cpp +++ b/dlls/talkmonster.cpp @@ -403,11 +403,11 @@ void CTalkMonster::StartTask( Task_t *pTask ) if( yaw < 0 ) { - pev->ideal_yaw = min( yaw + 45, 0 ) + pev->angles.y; + pev->ideal_yaw = Q_min( yaw + 45, 0 ) + pev->angles.y; } else { - pev->ideal_yaw = max( yaw - 45, 0 ) + pev->angles.y; + pev->ideal_yaw = Q_max( yaw - 45, 0 ) + pev->angles.y; } } TaskComplete(); diff --git a/dlls/turret.cpp b/dlls/turret.cpp index ae95db14..093b2032 100644 --- a/dlls/turret.cpp +++ b/dlls/turret.cpp @@ -454,7 +454,7 @@ void CBaseTurret::EyeOff() { if( m_eyeBrightness > 0 ) { - m_eyeBrightness = max( 0, m_eyeBrightness - 30 ); + m_eyeBrightness = Q_max( 0, m_eyeBrightness - 30 ); m_pEyeGlow->SetBrightness( m_eyeBrightness ); } } diff --git a/dlls/util.cpp b/dlls/util.cpp index 68ba30cd..f382ac58 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1112,7 +1112,7 @@ void UTIL_BloodStream( const Vector &origin, const Vector &direction, int color, WRITE_COORD( direction.y ); WRITE_COORD( direction.z ); WRITE_BYTE( color ); - WRITE_BYTE( min( amount, 255 ) ); + WRITE_BYTE( Q_min( amount, 255 ) ); MESSAGE_END(); } @@ -1144,7 +1144,7 @@ void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, WRITE_SHORT( g_sModelIndexBloodSpray ); // initial sprite model WRITE_SHORT( g_sModelIndexBloodDrop ); // droplet sprite models WRITE_BYTE( color ); // color index into host_basepal - WRITE_BYTE( min( max( 3, amount / 10 ), 16 ) ); // size + WRITE_BYTE( Q_min( Q_max( 3, amount / 10 ), 16 ) ); // size MESSAGE_END(); } diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index a1205f27..80a45284 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -607,7 +607,7 @@ void CBasePlayerWeapon::ItemPostFrame( void ) if( ( m_fInReload ) && ( m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase() ) ) { // complete the reload. - int j = min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); + int j = Q_min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); // Add them to the clip m_iClip += j; @@ -850,7 +850,7 @@ BOOL CBasePlayerWeapon::AddPrimaryAmmo( int iCount, char *szName, int iMaxClip, else if( m_iClip == 0 ) { int i; - i = min( m_iClip + iCount, iMaxClip ) - m_iClip; + i = Q_min( m_iClip + iCount, iMaxClip ) - m_iClip; m_iClip += i; iIdAmmo = m_pPlayer->GiveAmmo( iCount - i, szName, iMaxCarry ); } @@ -964,7 +964,7 @@ BOOL CBasePlayerWeapon::DefaultReload( int iClipSize, int iAnim, float fDelay, i if( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) return FALSE; - int j = min( iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ); + int j = Q_min( iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ); if( j == 0 ) return FALSE; @@ -1428,7 +1428,7 @@ int CWeaponBox::GiveAmmo( int iCount, const char *szName, int iMax, int *pIndex/ if( pIndex ) *pIndex = i; - int iAdd = min( iCount, iMax - m_rgAmmo[i] ); + int iAdd = Q_min( iCount, iMax - m_rgAmmo[i] ); if( iCount == 0 || iAdd > 0 ) { m_rgAmmo[i] += iAdd; From 8e799fcf6d4fc6f3f685e07173d6e538968695ac Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 15 Oct 2017 14:22:14 +0500 Subject: [PATCH 111/211] Add crowbar idle animations under CROWBAR_IDLE_ANIM macro. --- cl_dll/ev_hldm.cpp | 6 ++++++ dlls/crowbar.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- dlls/weapons.h | 3 +++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 80073b27..628b5bfa 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -1138,7 +1138,13 @@ enum crowbar_e CROWBAR_ATTACK2MISS, CROWBAR_ATTACK2HIT, CROWBAR_ATTACK3MISS, +#ifndef CROWBAR_IDLE_ANIM CROWBAR_ATTACK3HIT +#else + CROWBAR_ATTACK3HIT, + CROWBAR_IDLE2, + CROWBAR_IDLE3 +#endif }; int g_iSwing; diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index f9a91978..4cc48d97 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -37,7 +37,13 @@ enum crowbar_e CROWBAR_ATTACK2MISS, CROWBAR_ATTACK2HIT, CROWBAR_ATTACK3MISS, +#ifndef CROWBAR_IDLE_ANIM CROWBAR_ATTACK3HIT +#else + CROWBAR_ATTACK3HIT, + CROWBAR_IDLE2, + CROWBAR_IDLE3 +#endif }; void CCrowbar::Spawn() @@ -208,7 +214,9 @@ int CCrowbar::Swing( int fFirst ) { // miss m_flNextPrimaryAttack = GetNextAttackDelay( 0.5 ); - +#ifdef CROWBAR_IDLE_ANIM + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); +#endif // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); } @@ -324,5 +332,38 @@ int CCrowbar::Swing( int fFirst ) #endif m_flNextPrimaryAttack = GetNextAttackDelay( 0.25 ); } +#ifdef CROWBAR_IDLE_ANIM + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); +#endif return fDidHit; } + +#ifdef CROWBAR_IDLE_ANIM +void CCrowbar::WeaponIdle( void ) +{ + if( m_flTimeWeaponIdle < UTIL_WeaponTimeBase() ) + { + int iAnim; + float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 ); + if( flRand > 0.9 ) + { + iAnim = CROWBAR_IDLE2; + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 160.0 / 30.0; + } + else + { + if( flRand > 0.5 ) + { + iAnim = CROWBAR_IDLE; + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 70.0 / 30.0; + } + else + { + iAnim = CROWBAR_IDLE3; + m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 160.0 / 30.0; + } + } + SendWeaponAnim( iAnim ); + } +} +#endif diff --git a/dlls/weapons.h b/dlls/weapons.h index f48767c8..6c03105b 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -504,6 +504,9 @@ public: int Swing( int fFirst ); BOOL Deploy( void ); void Holster( int skiplocal = 0 ); +#ifdef CROWBAR_IDLE_ANIM + void WeaponIdle(); +#endif int m_iSwing; TraceResult m_trHit; From aaedd794c36cfae4bbecabf5ce9c55116307e3ee Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 15 Oct 2017 17:50:05 +0500 Subject: [PATCH 112/211] Merge https://github.com/LevShisterov/BugfixedHL/commit/293b41b8cd20f19179926284e4100f00e8e62fd7 --- dlls/player.cpp | 5 +++++ dlls/player.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/dlls/player.cpp b/dlls/player.cpp index 757f03e4..d0a1f763 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -2586,6 +2586,11 @@ void CBasePlayer::PostThink() UpdatePlayerSound(); pt_end: + if( pev->deadflag == DEAD_NO ) + m_vecLastViewAngles = pev->angles; + else + pev->angles = m_vecLastViewAngles; + // Track button info so we can detect 'pressed' and 'released' buttons next frame m_afButtonLast = pev->button; diff --git a/dlls/player.h b/dlls/player.h index 54e7fa85..fecaf3c9 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -306,6 +306,8 @@ public: void TabulateAmmo( void ); + Vector m_vecLastViewAngles; + float m_flStartCharge; float m_flAmmoStartCharge; float m_flPlayAftershock; From 5aa11a38b3148dd220321a745cbdb3194947f0ba Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 1 Nov 2017 16:43:29 +0300 Subject: [PATCH 113/211] Give player exhaustible weapons when taking ammo for them from weaponbox --- dlls/weapons.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 80a45284..5e4f8f78 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -1265,6 +1265,18 @@ void CWeaponBox::Kill( void ) UTIL_Remove( this ); } +static const char* IsAmmoForExhaustibleWeapon(const char* ammoName, int& weaponId) +{ + for (int i=0; im_rgpPlayerItems[j]; + while( pPlayerItem ) + { + if (pPlayerItem->m_iId == exhaustibleWeaponId) { + foundWeapon = true; + break; + } + pPlayerItem = pPlayerItem->m_pNext; + } + } + if (!foundWeapon) { + CBasePlayerWeapon* weapon = (CBasePlayerWeapon*)Create(weaponName, pev->origin, pev->angles); + if (weapon) { + weapon->pev->spawnflags |= SF_NORESPAWN; + weapon->m_iDefaultAmmo = 0; + if (pPlayer->AddPlayerItem(weapon)) { + weapon->AttachToPlayer(pPlayer); + } + } + } + } + // there's some ammo of this type. pPlayer->GiveAmmo( m_rgAmmo[i], STRING( m_rgiszAmmo[i] ), MaxAmmoCarry( m_rgiszAmmo[i] ) ); From 7d33351f77d7ac1f843c05a70bae8c9a8eabe8bf Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sat, 18 Nov 2017 14:49:01 +0500 Subject: [PATCH 114/211] Add missing file to build lists. --- dlls/Android.mk | 1 + dlls/CMakeLists.txt | 1 + dlls/Makefile | 1 + 3 files changed, 3 insertions(+) diff --git a/dlls/Android.mk b/dlls/Android.mk index b160c424..1dc79616 100644 --- a/dlls/Android.mk +++ b/dlls/Android.mk @@ -96,6 +96,7 @@ LOCAL_SRC_FILES := agrunt.cpp airtank.cpp \ plane.cpp \ plats.cpp \ player.cpp \ + playermonster.cpp \ python.cpp \ rat.cpp \ roach.cpp \ diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index e0b6a8b3..4e56ab44 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -98,6 +98,7 @@ set (SVDLL_SOURCES plane.cpp plats.cpp player.cpp + playermonster.cpp python.cpp rat.cpp roach.cpp diff --git a/dlls/Makefile b/dlls/Makefile index 9c3a84f2..60aad1b3 100644 --- a/dlls/Makefile +++ b/dlls/Makefile @@ -135,6 +135,7 @@ OBJ = \ $(DLL_OBJDIR)/plane.o \ $(DLL_OBJDIR)/plats.o \ $(DLL_OBJDIR)/player.o \ + $(DLL_OBJDIR)/playermonster.o \^M $(DLL_OBJDIR)/python.o \ $(DLL_OBJDIR)/rat.o \ $(DLL_OBJDIR)/roach.o \ From ad3a2141eb53a42b15dd6a994971900873530c9a Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sun, 3 Dec 2017 18:52:38 +0300 Subject: [PATCH 115/211] Change __MSC_VER to _MSC_VER to make the client buildable with VS 6 --- engine/cdll_int.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/cdll_int.h b/engine/cdll_int.h index d45bb9d5..20af4b55 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -93,7 +93,7 @@ typedef struct client_textmessage_s const char *pMessage; } client_textmessage_t; -#if __MSC_VER == 1200 +#if _MSC_VER == 1200 #define ulonglong_t __int64 #else #define ulonglong_t unsigned long long From 31b2a68d6d45bf4682043e9888b2f2b1f4f49df9 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Fri, 18 Nov 2016 01:05:05 +0300 Subject: [PATCH 116/211] goldsource mouse input --- CMakeLists.txt | 3 +- cl_dll/CMakeLists.txt | 42 +- cl_dll/input_goldsource.cpp | 1357 +++++++++++++++++++++++++++++++++++ cl_dll/inputw32.cpp | 901 ----------------------- 4 files changed, 1384 insertions(+), 919 deletions(-) create mode 100644 cl_dll/input_goldsource.cpp delete mode 100644 cl_dll/inputw32.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c2d6822..7719bac6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ option(USE_VGUI2 "Enable VGUI2. UNDONE" OFF) option(USE_VOICEMGR "Enable VOICE MANAGER." OFF) option(BUILD_CLIENT "Build client dll" ON) option(BUILD_SERVER "Build server dll" ON) +option(GOLDSOURCE_SUPPORT "Build goldsource compatible client library" OFF) #----------------- # MAIN BUILD CODE \ @@ -59,4 +60,4 @@ endif() if(NOT BUILD_SERVER AND NOT BUILD_CLIENT) error("Nothing to build") -endif() \ No newline at end of file +endif() diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 7fffb29b..7bd04f77 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -26,24 +26,27 @@ project (CLDLL) set (CLDLL_LIBRARY client) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w") +if (GOLDSOURCE_SUPPORT) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lSDL2 -Wl,--no-undefined") +endif() set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") -set (CLDLL_SOURCES - ../dlls/crossbow.cpp - ../dlls/crowbar.cpp - ../dlls/egon.cpp - ../dlls/gauss.cpp - ../dlls/handgrenade.cpp - ../dlls/hornetgun.cpp - ../dlls/mp5.cpp - ../dlls/python.cpp - ../dlls/rpg.cpp - ../dlls/satchel.cpp - ../dlls/shotgun.cpp - ../dlls/squeakgrenade.cpp - ../dlls/tripmine.cpp +set (CLDLL_SOURCES + ../dlls/crossbow.cpp + ../dlls/crowbar.cpp + ../dlls/egon.cpp + ../dlls/gauss.cpp + ../dlls/handgrenade.cpp + ../dlls/hornetgun.cpp + ../dlls/mp5.cpp + ../dlls/python.cpp + ../dlls/rpg.cpp + ../dlls/satchel.cpp + ../dlls/shotgun.cpp + ../dlls/squeakgrenade.cpp + ../dlls/tripmine.cpp ../dlls/glock.cpp - ev_hldm.cpp + ev_hldm.cpp hl/hl_baseentity.cpp hl/hl_events.cpp hl/hl_objects.cpp @@ -70,7 +73,6 @@ set (CLDLL_SOURCES hud_update.cpp in_camera.cpp input.cpp -#SRCS+=./inputw32.cpp menu.cpp message.cpp overview.cpp @@ -88,9 +90,15 @@ set (CLDLL_SOURCES tri.cpp util.cpp view.cpp - input_xash3d.cpp scoreboard.cpp MOTD.cpp) + +if (GOLDSOURCE_SUPPORT) + set (CLDLL_SOURCES "${CLDLL_SOURCES}" input_goldsource.cpp) +else() + set (CLDLL_SOURCES "${CLDLL_SOURCES}" input_xash3d.cpp) +endif() + include_directories (. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public) if(USE_VOICEMGR) diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp new file mode 100644 index 00000000..70cd23c5 --- /dev/null +++ b/cl_dll/input_goldsource.cpp @@ -0,0 +1,1357 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +// in_win.c -- windows 95 mouse and joystick code +// 02/21/97 JCB Added extended DirectInput code to support external controllers. + +//#include "port.h" + +#include "hud.h" +#include "cl_util.h" +#include "camera.h" +#include "kbutton.h" +#include "cvardef.h" +#include "usercmd.h" +#include "const.h" +#include "camera.h" +#include "in_defs.h" +#include "keydefs.h" +#include "view.h" +//#include "Exports.h" + +#ifndef _WIN32 +#define USE_SDL2 +#endif + +#ifdef USE_SDL2 +#include +#include +#endif + +#ifdef _WIN32 +#include +#else +typedef unsigned int DWORD; +#endif + +#define MOUSE_BUTTON_COUNT 5 + +// use IN_SetVisibleMouse to set: +int iVisibleMouse = 0; + +extern cl_enginefunc_t gEngfuncs; + +extern int iMouseInUse; + +extern kbutton_t in_strafe; +extern kbutton_t in_mlook; +extern kbutton_t in_speed; +extern kbutton_t in_jlook; + +extern cvar_t *m_pitch; +extern cvar_t *m_yaw; +extern cvar_t *m_forward; +extern cvar_t *m_side; + +extern cvar_t *lookstrafe; +extern cvar_t *lookspring; +extern cvar_t *cl_pitchdown; +extern cvar_t *cl_pitchup; +extern cvar_t *cl_yawspeed; +extern cvar_t *cl_sidespeed; +extern cvar_t *cl_forwardspeed; +extern cvar_t *cl_pitchspeed; +extern cvar_t *cl_movespeedkey; + +#ifdef _WIN32 +static double s_flRawInputUpdateTime = 0.0f; +static bool m_bRawInput = false; +static bool m_bMouseThread = false; +bool isMouseRelative = false; +#endif + +#ifdef _WIN32 +#include "progdefs.h" +extern globalvars_t *gpGlobals; +#endif + +Vector dead_viewangles(0, 0, 0); + +void V_StopPitchDrift( void ) +{ + +} + +// mouse variables +cvar_t *m_filter; +cvar_t *sensitivity; + +// Custom mouse acceleration (0 disable, 1 to enable, 2 enable with separate yaw/pitch rescale) +static cvar_t *m_customaccel; +//Formula: mousesensitivity = ( rawmousedelta^m_customaccel_exponent ) * m_customaccel_scale + sensitivity +// If mode is 2, then x and y sensitivity are scaled by m_pitch and m_yaw respectively. +// Custom mouse acceleration value. +static cvar_t *m_customaccel_scale; +//Max mouse move scale factor, 0 for no limit +static cvar_t *m_customaccel_max; +//Mouse move is raised to this power before being scaled by scale factor +static cvar_t *m_customaccel_exponent; + +#ifdef _WIN32 +// if threaded mouse is enabled then the time to sleep between polls +static cvar_t *m_mousethread_sleep; +#endif + +int mouse_buttons; +int mouse_oldbuttonstate; +POINT current_pos; +int old_mouse_x, old_mouse_y, mx_accum, my_accum; +float mouse_x, mouse_y; + +static int restore_spi; +static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; +static int mouseactive = 0; +int mouseinitialized; +static int mouseparmsvalid; +static int mouseshowtoggle = 1; + +// joystick defines and variables +// where should defines be moved? +#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick +#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball +#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V +#define JOY_AXIS_X 0 +#define JOY_AXIS_Y 1 +#define JOY_AXIS_Z 2 +#define JOY_AXIS_R 3 +#define JOY_AXIS_U 4 +#define JOY_AXIS_V 5 + +enum _ControlList +{ + AxisNada = 0, + AxisForward, + AxisLook, + AxisSide, + AxisTurn +}; + + +DWORD dwAxisMap[ JOY_MAX_AXES ]; +DWORD dwControlMap[ JOY_MAX_AXES ]; +int pdwRawValue[ JOY_MAX_AXES ]; +DWORD joy_oldbuttonstate, joy_oldpovstate; + +int joy_id; +DWORD joy_numbuttons; + +#ifdef USE_SDL2 +SDL_GameController *s_pJoystick = NULL; +#endif + +// none of these cvars are saved over a session +// this means that advanced controller configuration needs to be executed +// each time. this avoids any problems with getting back to a default usage +// or when changing from one controller to another. this way at least something +// works. +cvar_t *in_joystick; +cvar_t *joy_name; +cvar_t *joy_advanced; +cvar_t *joy_advaxisx; +cvar_t *joy_advaxisy; +cvar_t *joy_advaxisz; +cvar_t *joy_advaxisr; +cvar_t *joy_advaxisu; +cvar_t *joy_advaxisv; +cvar_t *joy_forwardthreshold; +cvar_t *joy_sidethreshold; +cvar_t *joy_pitchthreshold; +cvar_t *joy_yawthreshold; +cvar_t *joy_forwardsensitivity; +cvar_t *joy_sidesensitivity; +cvar_t *joy_pitchsensitivity; +cvar_t *joy_yawsensitivity; +cvar_t *joy_wwhack1; +cvar_t *joy_wwhack2; + +int joy_avail, joy_advancedinit, joy_haspov; + +#ifdef _WIN32 +unsigned int s_hMouseThreadId = 0; +HANDLE s_hMouseThread = 0; +HANDLE s_hMouseQuitEvent = 0; +HANDLE s_hMouseThreadActiveLock = 0; +#endif + +/* +=========== +Force_CenterView_f +=========== +*/ +void Force_CenterView_f (void) +{ + vec3_t viewangles; + + if (!iMouseInUse) + { + gEngfuncs.GetViewAngles( (float *)viewangles ); + viewangles[PITCH] = 0; + gEngfuncs.SetViewAngles( (float *)viewangles ); + } +} + +#ifdef _WIN32 + +LONG mouseThreadActive = 0; +LONG mouseThreadCenterX = 0; +LONG mouseThreadCenterY = 0; +LONG mouseThreadDeltaX = 0; +LONG mouseThreadDeltaY = 0; +LONG mouseThreadSleep = 0; + +bool MouseThread_ActiveLock_Enter( void ) +{ + if(!m_bMouseThread) + return true; + + return WAIT_OBJECT_0 == WaitForSingleObject( s_hMouseThreadActiveLock, INFINITE); +} + +void MouseThread_ActiveLock_Exit( void ) +{ + if(!m_bMouseThread) + return; + + SetEvent( s_hMouseThreadActiveLock ); +} + +unsigned __stdcall MouseThread_Function( void * pArg ) +{ + while ( true ) + { + DWORD sleepVal = (DWORD)InterlockedExchangeAdd(&mouseThreadSleep, 0); + if(0 > sleepVal) sleepVal = 0; + else if(1000 < sleepVal) sleepVal = 1000; + if(WAIT_OBJECT_0 == WaitForSingleObject( s_hMouseQuitEvent, sleepVal)) + { + break; + } + + if( MouseThread_ActiveLock_Enter() ) + { + if ( InterlockedExchangeAdd(&mouseThreadActive, 0) ) + { + POINT mouse_pos; + POINT center_pos; + + center_pos.x = InterlockedExchangeAdd(&mouseThreadCenterX, 0); + center_pos.y = InterlockedExchangeAdd(&mouseThreadCenterY, 0); + GetCursorPos(&mouse_pos); + + mouse_pos.x -= center_pos.x; + mouse_pos.y -= center_pos.y; + + if(mouse_pos.x || mouse_pos.y) SetCursorPos( center_pos.x, center_pos.y ); + + InterlockedExchangeAdd(&mouseThreadDeltaX, mouse_pos.x); + InterlockedExchangeAdd(&mouseThreadDeltaY, mouse_pos.y); + } + + MouseThread_ActiveLock_Exit(); + } + } + + return 0; +} + +/// Updates mouseThreadActive using the global variables mouseactive, iVisibleMouse and m_bRawInput. Should be called after any of these is changed. +/// Has to be interlocked manually by programmer! Use MouseThread_ActiveLock_Enter and MouseThread_ActiveLock_Exit. +void UpdateMouseThreadActive(void) +{ + InterlockedExchange(&mouseThreadActive, mouseactive && !iVisibleMouse && !m_bRawInput); +} + +#endif + +void IN_SetMouseMode(bool enable) +{ + static bool currentMouseMode = false; + + if(enable == currentMouseMode) + return; + + if(enable) + { +#ifdef _WIN32 + if (mouseparmsvalid) + restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); + + m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; + if(m_bRawInput) + { +#ifdef USE_SDL2 + SDL_SetRelativeMouseMode(SDL_TRUE); +#endif + isMouseRelative = true; + } +#else + SDL_SetRelativeMouseMode(SDL_TRUE); +#endif + + currentMouseMode = true; + } + else + { +#ifdef _WIN32 + if(isMouseRelative) + { +#ifdef USE_SDL2 + SDL_SetRelativeMouseMode(SDL_FALSE); +#endif + isMouseRelative = false; + } + + if (restore_spi) + SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); +#else + SDL_SetRelativeMouseMode(SDL_FALSE); +#endif + + currentMouseMode = false; + } +} + +void IN_SetVisibleMouse(bool visible) +{ +#ifdef _WIN32 + bool lockEntered = MouseThread_ActiveLock_Enter(); +#endif + + iVisibleMouse = visible; + + IN_SetMouseMode(!visible); + +#ifdef _WIN32 + UpdateMouseThreadActive(); + if(lockEntered) MouseThread_ActiveLock_Exit(); +#endif +} + +void IN_ResetMouse( void ); + +/* +=========== +IN_ActivateMouse +=========== +*/ +extern "C" void DLLEXPORT IN_ActivateMouse (void) +{ + if (mouseinitialized) + { +#ifdef _WIN32 + bool lockEntered = MouseThread_ActiveLock_Enter(); +#endif + + IN_SetMouseMode(true); + + mouseactive = 1; + +#ifdef _WIN32 + UpdateMouseThreadActive(); + if(lockEntered) MouseThread_ActiveLock_Exit(); +#endif + + // now is a good time to reset mouse positon: + IN_ResetMouse(); + } +} + + +/* +=========== +IN_DeactivateMouse +=========== +*/ +extern "C" void DLLEXPORT IN_DeactivateMouse (void) +{ + if (mouseinitialized) + { +#ifdef _WIN32 + bool lockEntered = MouseThread_ActiveLock_Enter(); +#endif + + IN_SetMouseMode(false); + + mouseactive = 0; + +#ifdef _WIN32 + UpdateMouseThreadActive(); + if(lockEntered) MouseThread_ActiveLock_Exit(); +#endif + } +} + +/* +=========== +IN_StartupMouse +=========== +*/ +void IN_StartupMouse (void) +{ + if ( gEngfuncs.CheckParm ("-nomouse", NULL ) ) + return; + + mouseinitialized = 1; +#ifdef _WIN32 + mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); + + if (mouseparmsvalid) + { + if ( gEngfuncs.CheckParm ("-noforcemspd", NULL ) ) + newmouseparms[2] = originalmouseparms[2]; + + if ( gEngfuncs.CheckParm ("-noforcemaccel", NULL ) ) + { + newmouseparms[0] = originalmouseparms[0]; + newmouseparms[1] = originalmouseparms[1]; + } + + if ( gEngfuncs.CheckParm ("-noforcemparms", NULL ) ) + { + newmouseparms[0] = originalmouseparms[0]; + newmouseparms[1] = originalmouseparms[1]; + newmouseparms[2] = originalmouseparms[2]; + } + } +#endif + + mouse_buttons = MOUSE_BUTTON_COUNT; +} + +/* +=========== +IN_Shutdown +=========== +*/ +void IN_Shutdown (void) +{ + IN_DeactivateMouse (); + +#ifdef _WIN32 + if ( s_hMouseQuitEvent ) + { + SetEvent( s_hMouseQuitEvent ); + } + + if ( s_hMouseThread ) + { + if(WAIT_OBJECT_0 != WaitForSingleObject( s_hMouseThread, 5000 )) + { + TerminateThread( s_hMouseThread, 0 ); + } + CloseHandle( s_hMouseThread ); + s_hMouseThread = (HANDLE)0; + } + + if ( s_hMouseQuitEvent ) + { + CloseHandle( s_hMouseQuitEvent ); + s_hMouseQuitEvent = (HANDLE)0; + } + + if( s_hMouseThreadActiveLock ) + { + CloseHandle( s_hMouseThreadActiveLock ); + s_hMouseThreadActiveLock = (HANDLE)0; + } +#endif +} + +/* +=========== +IN_GetMousePos + +Ask for mouse position from engine +=========== +*/ +void IN_GetMousePos( int *mx, int *my ) +{ + gEngfuncs.GetMousePosition( mx, my ); +} + +/* +=========== +IN_ResetMouse + +FIXME: Call through to engine? +=========== +*/ +void IN_ResetMouse( void ) +{ + // no work to do in SDL +#ifdef _WIN32 + // reset only if mouse is active and not in visible mode: + if(mouseactive && !iVisibleMouse) + { + if ( !m_bRawInput && gEngfuncs.GetWindowCenterX && gEngfuncs.GetWindowCenterY ) + { + bool lockEntered = MouseThread_ActiveLock_Enter(); + + int centerX = gEngfuncs.GetWindowCenterX(); + int centerY = gEngfuncs.GetWindowCenterY(); + + SetCursorPos ( centerX, centerY ); + InterlockedExchange( &mouseThreadCenterX, centerX ); + InterlockedExchange( &mouseThreadCenterY, centerY ); + InterlockedExchange( &mouseThreadDeltaX, 0 ); + InterlockedExchange( &mouseThreadDeltaY, 0 ); + + if(lockEntered) MouseThread_ActiveLock_Exit(); + } + } +#endif +} + +/* +=========== +IN_MouseEvent +=========== +*/ +extern "C" void DLLEXPORT IN_MouseEvent (int mstate) +{ + int i; + + if ( iMouseInUse || iVisibleMouse ) + return; + + // perform button actions + for (i=0 ; ivalue; + + // Using special accleration values + if ( m_customaccel->value != 0 ) + { + float raw_mouse_movement_distance = sqrt( mx * mx + my * my ); + float acceleration_scale = m_customaccel_scale->value; + float accelerated_sensitivity_max = m_customaccel_max->value; + float accelerated_sensitivity_exponent = m_customaccel_exponent->value; + float accelerated_sensitivity = ( (float)pow( raw_mouse_movement_distance, accelerated_sensitivity_exponent ) * acceleration_scale + mouse_senstivity ); + + if ( accelerated_sensitivity_max > 0.0001f && + accelerated_sensitivity > accelerated_sensitivity_max ) + { + accelerated_sensitivity = accelerated_sensitivity_max; + } + + *x *= accelerated_sensitivity; + *y *= accelerated_sensitivity; + + // Further re-scale by yaw and pitch magnitude if user requests alternate mode 2 + // This means that they will need to up their value for m_customaccel_scale greatly (>40x) since m_pitch/yaw default + // to 0.022 + if ( m_customaccel->value == 2 ) + { + *x *= m_yaw->value; + *y *= m_pitch->value; + } + } + else + { + // Just apply the default + *x *= mouse_senstivity; + *y *= mouse_senstivity; + } +} + +void IN_GetMouseDelta( int *pOutX, int *pOutY) +{ + bool active = mouseactive && !iVisibleMouse; + int mx, my; + + if(active) + { + int deltaX, deltaY; +#ifdef _WIN32 + if ( !m_bRawInput ) + { + if ( m_bMouseThread ) + { + // update mouseThreadSleep: + InterlockedExchange(&mouseThreadSleep, (LONG)m_mousethread_sleep->value); + + bool lockEntered = MouseThread_ActiveLock_Enter(); + + current_pos.x = InterlockedExchange( &mouseThreadDeltaX, 0 ); + current_pos.y = InterlockedExchange( &mouseThreadDeltaY, 0 ); + + if(lockEntered) MouseThread_ActiveLock_Exit(); + } + else + { + GetCursorPos (¤t_pos); + } + } + else +#endif + { +#ifdef USE_SDL2 + SDL_GetRelativeMouseState( &deltaX, &deltaY ); + current_pos.x = deltaX; + current_pos.y = deltaY; +#else + GetCursorPos (¤t_pos); + deltaX = current_pos.x - gEngfuncs.GetWindowCenterX(); + deltaY = current_pos.y - gEngfuncs.GetWindowCenterY(); +#endif + } + +#ifdef _WIN32 + if ( !m_bRawInput ) + { + if ( m_bMouseThread ) + { + mx = current_pos.x; + my = current_pos.y; + } + else + { + mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum; + my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum; + } + } + else +#endif + { + mx = deltaX + mx_accum; + my = deltaY + my_accum; + } + + mx_accum = 0; + my_accum = 0; + + // reset mouse position if required, so there is room to move: +#ifdef _WIN32 + // do not reset if mousethread would do it: + if ( m_bRawInput || !m_bMouseThread ) +#else + if(true) +#endif + IN_ResetMouse(); + +#ifdef _WIN32 + // update m_bRawInput occasionally: + if ( gpGlobals && gpGlobals->time - s_flRawInputUpdateTime > 1.0f ) + { + s_flRawInputUpdateTime = gpGlobals->time; + + bool lockEntered = MouseThread_ActiveLock_Enter(); + + m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; + + if(m_bRawInput && !isMouseRelative) + { +#ifdef USE_SDL2 + SDL_SetRelativeMouseMode(SDL_TRUE); +#endif + isMouseRelative = true; + } + else if(!m_bRawInput && isMouseRelative) + { +#ifdef USE_SDL2 + SDL_SetRelativeMouseMode(SDL_FALSE); +#endif + isMouseRelative = false; + } + + UpdateMouseThreadActive(); + if(lockEntered) MouseThread_ActiveLock_Exit(); + } +#endif + } + else + { + mx = my = 0; + } + + if(pOutX) *pOutX = mx; + if(pOutY) *pOutY = my; +} + +/* +=========== +IN_MouseMove +=========== +*/ +void IN_MouseMove ( float frametime, usercmd_t *cmd) +{ + int mx, my; + vec3_t viewangles; + + gEngfuncs.GetViewAngles( (float *)viewangles ); + + if ( in_mlook.state & 1) + { + V_StopPitchDrift (); + } + + //jjb - this disbles normal mouse control if the user is trying to + // move the camera, or if the mouse cursor is visible or if we're in intermission + if ( !iMouseInUse && !gHUD.m_iIntermission && !iVisibleMouse ) + { + IN_GetMouseDelta( &mx, &my ); + + if (m_filter && m_filter->value) + { + mouse_x = (mx + old_mouse_x) * 0.5; + mouse_y = (my + old_mouse_y) * 0.5; + } + else + { + mouse_x = mx; + mouse_y = my; + } + + old_mouse_x = mx; + old_mouse_y = my; + + // Apply custom mouse scaling/acceleration + IN_ScaleMouse( &mouse_x, &mouse_y ); + + // add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) )) + cmd->sidemove += m_side->value * mouse_x; + else + viewangles[YAW] -= m_yaw->value * mouse_x; + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + viewangles[PITCH] += m_pitch->value * mouse_y; + if (viewangles[PITCH] > cl_pitchdown->value) + viewangles[PITCH] = cl_pitchdown->value; + if (viewangles[PITCH] < -cl_pitchup->value) + viewangles[PITCH] = -cl_pitchup->value; + } + else + { + if ((in_strafe.state & 1) && gEngfuncs.IsNoClipping() ) + { + cmd->upmove -= m_forward->value * mouse_y; + } + else + { + cmd->forwardmove -= m_forward->value * mouse_y; + } + } + } + + gEngfuncs.SetViewAngles( (float *)viewangles ); + +/* +//#define TRACE_TEST +#if defined( TRACE_TEST ) + { + int mx, my; + void V_Move( int mx, int my ); + IN_GetMousePos( &mx, &my ); + V_Move( mx, my ); + } +#endif +*/ +} + +/* +=========== +IN_Accumulate +=========== +*/ +extern "C" void DLLEXPORT IN_Accumulate (void) +{ + //only accumulate mouse if we are not moving the camera with the mouse + if ( !iMouseInUse && !iVisibleMouse) + { + if (mouseactive) + { +#ifdef _WIN32 + if ( !m_bRawInput ) + { + if ( !m_bMouseThread ) + { + GetCursorPos (¤t_pos); + + mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); + my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); + } + } + else +#endif + { +#ifdef USE_SDL2 + int deltaX, deltaY; + SDL_GetRelativeMouseState( &deltaX, &deltaY ); + mx_accum += deltaX; + my_accum += deltaY; +#else + GetCursorPos (¤t_pos); + + mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); + my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); +#endif + } + + // force the mouse to the center, so there's room to move +#ifdef _WIN32 + // do not reset if mousethread would do it: + if ( m_bRawInput || !m_bMouseThread ) +#else + if(true) +#endif + IN_ResetMouse(); + + } + } + +} + +/* +=================== +IN_ClearStates +=================== +*/ +extern "C" void DLLEXPORT IN_ClearStates (void) +{ + if ( !mouseactive ) + return; + + mx_accum = 0; + my_accum = 0; + mouse_oldbuttonstate = 0; +} + +/* +=============== +IN_StartupJoystick +=============== +*/ +void IN_StartupJoystick (void) +{ + // abort startup if user requests no joystick + if ( gEngfuncs.CheckParm ("-nojoy", NULL ) ) + return; + + // assume no joystick + joy_avail = 0; +#ifdef USE_SDL2 + int nJoysticks = SDL_NumJoysticks(); + if ( nJoysticks > 0 ) + { + for ( int i = 0; i < nJoysticks; i++ ) + { + if ( SDL_IsGameController( i ) ) + { + s_pJoystick = SDL_GameControllerOpen( i ); + if ( s_pJoystick ) + { + //save the joystick's number of buttons and POV status + joy_numbuttons = SDL_CONTROLLER_BUTTON_MAX; + joy_haspov = 0; + + // old button and POV states default to no buttons pressed + joy_oldbuttonstate = joy_oldpovstate = 0; + + // mark the joystick as available and advanced initialization not completed + // this is needed as cvars are not available during initialization + gEngfuncs.Con_Printf ("joystick found\n\n", SDL_GameControllerName(s_pJoystick)); + joy_avail = 1; + joy_advancedinit = 0; + break; + } + } + } + } + else + { + gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); + } +#else + gEngfuncs.Con_DPrintf ("joystick not found -- implement joystick without SDL2\n\n"); +#endif +} + +int RawValuePointer (int axis) +{ +#ifdef USE_SDL2 + switch (axis) + { + default: + case JOY_AXIS_X: + return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX ); + case JOY_AXIS_Y: + return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY ); + case JOY_AXIS_Z: + return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX ); + case JOY_AXIS_R: + return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY ); + + } +#else + // TODO: implement joystick without SDL2 + return 0; +#endif +} + +/* +=========== +Joy_AdvancedUpdate_f +=========== +*/ +void Joy_AdvancedUpdate_f (void) +{ + + // called once by IN_ReadJoystick and by user whenever an update is needed + // cvars are now available + int i; + DWORD dwTemp; + + // initialize all the maps + for (i = 0; i < JOY_MAX_AXES; i++) + { + dwAxisMap[i] = AxisNada; + dwControlMap[i] = JOY_ABSOLUTE_AXIS; + pdwRawValue[i] = RawValuePointer(i); + } + + if( joy_advanced->value == 0.0) + { + // default joystick initialization + // 2 axes only with joystick control + dwAxisMap[JOY_AXIS_X] = AxisTurn; + // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; + dwAxisMap[JOY_AXIS_Y] = AxisForward; + // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; + } + else + { + if ( strcmp ( joy_name->string, "joystick") != 0 ) + { + // notify user of advanced controller + gEngfuncs.Con_Printf ("\n%s configured\n\n", joy_name->string); + } + + // advanced initialization here + // data supplied by user via joy_axisn cvars + dwTemp = (DWORD) joy_advaxisx->value; + dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisy->value; + dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisz->value; + dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisr->value; + dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisu->value; + dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisv->value; + dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; + } +} + + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + int i, key_index; + + if (!joy_avail) + { + return; + } + + DWORD buttonstate, povstate; + + // loop through the joystick buttons + // key a joystick event or auxillary event for higher number buttons for each state change + buttonstate = 0; +#ifdef USE_SDL2 + for ( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) + { + if ( SDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) ) + { + buttonstate |= 1<value) + { + return; + } + + // collect the joystick data, if possible + if (IN_ReadJoystick () != 1) + { + return; + } + + if (in_speed.state & 1) + speed = cl_movespeedkey->value; + else + speed = 1; + + aspeed = speed * frametime; + + // loop through the axes + for (i = 0; i < JOY_MAX_AXES; i++) + { + // get the floating point zero-centered, potentially-inverted data for the current axis + fAxisValue = (float)pdwRawValue[i]; + + if (joy_wwhack2->value != 0.0) + { + if (dwAxisMap[i] == AxisTurn) + { + // this is a special formula for the Logitech WingMan Warrior + // y=ax^b; where a = 300 and b = 1.3 + // also x values are in increments of 800 (so this is factored out) + // then bounds check result to level out excessively high spin rates + fTemp = 300.0 * pow(abs(fAxisValue) / 800.0, 1.3); + if (fTemp > 14000.0) + fTemp = 14000.0; + // restore direction information + fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp; + } + } + + // convert range from -32768..32767 to -1..1 + fAxisValue /= 32768.0; + + switch (dwAxisMap[i]) + { + case AxisForward: + if ((joy_advanced->value == 0.0) && (in_jlook.state & 1)) + { + // user wants forward control to become look control + if (fabs(fAxisValue) > joy_pitchthreshold->value) + { + // if mouse invert is on, invert the joystick pitch value + // only absolute control support here (joy_advanced is 0) + if (m_pitch->value < 0.0) + { + viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; + } + else + { + viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; + } + V_StopPitchDrift(); + } + else + { + // no pitch movement + // disable pitch return-to-center unless requested by user + // *** this code can be removed when the lookspring bug is fixed + // *** the bug always has the lookspring feature on + if(lookspring->value == 0.0) + { + V_StopPitchDrift(); + } + } + } + else + { + // user wants forward control to be forward control + if (fabs(fAxisValue) > joy_forwardthreshold->value) + { + cmd->forwardmove += (fAxisValue * joy_forwardsensitivity->value) * speed * cl_forwardspeed->value; + } + } + break; + + case AxisSide: + if (fabs(fAxisValue) > joy_sidethreshold->value) + { + cmd->sidemove += (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; + } + break; + + case AxisTurn: + if ((in_strafe.state & 1) || (lookstrafe->value && (in_jlook.state & 1))) + { + // user wants turn control to become side control + if (fabs(fAxisValue) > joy_sidethreshold->value) + { + cmd->sidemove -= (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; + } + } + else + { + // user wants turn control to be turn control + if (fabs(fAxisValue) > joy_yawthreshold->value) + { + if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) + { + viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * aspeed * cl_yawspeed->value; + } + else + { + viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * speed * 180.0; + } + + } + } + break; + + case AxisLook: + if (in_jlook.state & 1) + { + if (fabs(fAxisValue) > joy_pitchthreshold->value) + { + // pitch movement detected and pitch movement desired by user + if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) + { + viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; + } + else + { + viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * speed * 180.0; + } + V_StopPitchDrift(); + } + else + { + // no pitch movement + // disable pitch return-to-center unless requested by user + // *** this code can be removed when the lookspring bug is fixed + // *** the bug always has the lookspring feature on + if( lookspring->value == 0.0 ) + { + V_StopPitchDrift(); + } + } + } + break; + + default: + break; + } + } + + // bounds check pitch + if (viewangles[PITCH] > cl_pitchdown->value) + viewangles[PITCH] = cl_pitchdown->value; + if (viewangles[PITCH] < -cl_pitchup->value) + viewangles[PITCH] = -cl_pitchup->value; + + gEngfuncs.SetViewAngles( (float *)viewangles ); +} + +/* +=========== +IN_Move +=========== +*/ +void IN_Move ( float frametime, usercmd_t *cmd) +{ + if ( !iMouseInUse && mouseactive ) + { + IN_MouseMove ( frametime, cmd); + } + + IN_JoyMove ( frametime, cmd); +} + +/* +=========== +IN_Init +=========== +*/ +void IN_Init (void) +{ + m_filter = gEngfuncs.pfnRegisterVariable ( "m_filter","0", FCVAR_ARCHIVE ); + sensitivity = gEngfuncs.pfnRegisterVariable ( "sensitivity","3", FCVAR_ARCHIVE ); // user mouse sensitivity setting. + + in_joystick = gEngfuncs.pfnRegisterVariable ( "joystick","0", FCVAR_ARCHIVE ); + joy_name = gEngfuncs.pfnRegisterVariable ( "joyname", "joystick", 0 ); + joy_advanced = gEngfuncs.pfnRegisterVariable ( "joyadvanced", "0", 0 ); + joy_advaxisx = gEngfuncs.pfnRegisterVariable ( "joyadvaxisx", "0", 0 ); + joy_advaxisy = gEngfuncs.pfnRegisterVariable ( "joyadvaxisy", "0", 0 ); + joy_advaxisz = gEngfuncs.pfnRegisterVariable ( "joyadvaxisz", "0", 0 ); + joy_advaxisr = gEngfuncs.pfnRegisterVariable ( "joyadvaxisr", "0", 0 ); + joy_advaxisu = gEngfuncs.pfnRegisterVariable ( "joyadvaxisu", "0", 0 ); + joy_advaxisv = gEngfuncs.pfnRegisterVariable ( "joyadvaxisv", "0", 0 ); + joy_forwardthreshold = gEngfuncs.pfnRegisterVariable ( "joyforwardthreshold", "0.15", 0 ); + joy_sidethreshold = gEngfuncs.pfnRegisterVariable ( "joysidethreshold", "0.15", 0 ); + joy_pitchthreshold = gEngfuncs.pfnRegisterVariable ( "joypitchthreshold", "0.15", 0 ); + joy_yawthreshold = gEngfuncs.pfnRegisterVariable ( "joyyawthreshold", "0.15", 0 ); + joy_forwardsensitivity = gEngfuncs.pfnRegisterVariable ( "joyforwardsensitivity", "-1.0", 0 ); + joy_sidesensitivity = gEngfuncs.pfnRegisterVariable ( "joysidesensitivity", "-1.0", 0 ); + joy_pitchsensitivity = gEngfuncs.pfnRegisterVariable ( "joypitchsensitivity", "1.0", 0 ); + joy_yawsensitivity = gEngfuncs.pfnRegisterVariable ( "joyyawsensitivity", "-1.0", 0 ); + joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 ); + joy_wwhack2 = gEngfuncs.pfnRegisterVariable ( "joywwhack2", "0.0", 0 ); + + m_customaccel = gEngfuncs.pfnRegisterVariable ( "m_customaccel", "0", FCVAR_ARCHIVE ); + m_customaccel_scale = gEngfuncs.pfnRegisterVariable ( "m_customaccel_scale", "0.04", FCVAR_ARCHIVE ); + m_customaccel_max = gEngfuncs.pfnRegisterVariable ( "m_customaccel_max", "0", FCVAR_ARCHIVE ); + m_customaccel_exponent = gEngfuncs.pfnRegisterVariable ( "m_customaccel_exponent", "1", FCVAR_ARCHIVE ); + +#ifdef _WIN32 + m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; + m_bMouseThread = gEngfuncs.CheckParm ("-mousethread", NULL ) != NULL; + m_mousethread_sleep = gEngfuncs.pfnRegisterVariable ( "m_mousethread_sleep", "1", FCVAR_ARCHIVE ); // default to less than 1000 Hz + + m_bMouseThread = m_bMouseThread && NULL != m_mousethread_sleep; + + if (m_bMouseThread) + { + // init mouseThreadSleep: +#if 0 // _beginthreadex is not defined on VS 6? + InterlockedExchange(&mouseThreadSleep, (LONG)m_mousethread_sleep->value); + + s_hMouseQuitEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); + s_hMouseThreadActiveLock = CreateEvent( NULL, FALSE, TRUE, NULL ); + if ( s_hMouseQuitEvent && s_hMouseThreadActiveLock) + { + s_hMouseThread = (HANDLE)_beginthreadex( NULL, 0, MouseThread_Function, NULL, 0, &s_hMouseThreadId ); + } + + m_bMouseThread = NULL != s_hMouseThread; +#else + m_bMouseThread = 0; +#endif + + // at this early stage this won't print anything: + // gEngfuncs.Con_DPrintf ("Mouse thread %s.\n", m_bMouseThread ? "initalized" : "failed to initalize"); + } +#endif + + gEngfuncs.pfnAddCommand ("force_centerview", Force_CenterView_f); + gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); + + IN_StartupMouse (); + IN_StartupJoystick (); +} diff --git a/cl_dll/inputw32.cpp b/cl_dll/inputw32.cpp deleted file mode 100644 index 5c8210fa..00000000 --- a/cl_dll/inputw32.cpp +++ /dev/null @@ -1,901 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// in_win.c -- windows 95 mouse and joystick code -// 02/21/97 JCB Added extended DirectInput code to support external controllers. - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "../engine/keydefs.h" -//#include "view.h" -#include "windows.h" - -#define MOUSE_BUTTON_COUNT 5 - -// Set this to 1 to show mouse cursor. Experimental -int g_iVisibleMouse = 0; - -extern "C" -{ - void DLLEXPORT IN_ActivateMouse( void ); - void DLLEXPORT IN_DeactivateMouse( void ); - void DLLEXPORT IN_MouseEvent( int mstate ); - void DLLEXPORT IN_Accumulate( void ); - void DLLEXPORT IN_ClearStates( void ); -} - -extern cl_enginefunc_t gEngfuncs; - -extern int iMouseInUse; - -extern kbutton_t in_strafe; -extern kbutton_t in_mlook; -extern kbutton_t in_speed; -extern kbutton_t in_jlook; - -extern cvar_t *m_pitch; -extern cvar_t *m_yaw; -extern cvar_t *m_forward; -extern cvar_t *m_side; - -extern cvar_t *lookstrafe; -extern cvar_t *lookspring; -extern cvar_t *cl_pitchdown; -extern cvar_t *cl_pitchup; -extern cvar_t *cl_yawspeed; -extern cvar_t *cl_sidespeed; -extern cvar_t *cl_forwardspeed; -extern cvar_t *cl_pitchspeed; -extern cvar_t *cl_movespeedkey; - -// mouse variables -cvar_t *m_filter; -cvar_t *sensitivity; - -int mouse_buttons; -int mouse_oldbuttonstate; -POINT current_pos; -int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum; - -static int restore_spi; -static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; -static int mouseactive; -int mouseinitialized; -static int mouseparmsvalid; -static int mouseshowtoggle = 1; - -// joystick defines and variables -// where should defines be moved? -#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick -#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball -#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V -#define JOY_AXIS_X 0 -#define JOY_AXIS_Y 1 -#define JOY_AXIS_Z 2 -#define JOY_AXIS_R 3 -#define JOY_AXIS_U 4 -#define JOY_AXIS_V 5 - -enum _ControlList -{ - AxisNada = 0, - AxisForward, - AxisLook, - AxisSide, - AxisTurn -}; - -DWORD dwAxisFlags[JOY_MAX_AXES] = -{ - JOY_RETURNX, - JOY_RETURNY, - JOY_RETURNZ, - JOY_RETURNR, - JOY_RETURNU, - JOY_RETURNV -}; - -DWORD dwAxisMap[JOY_MAX_AXES]; -DWORD dwControlMap[JOY_MAX_AXES]; -PDWORD pdwRawValue[JOY_MAX_AXES]; - -// none of these cvars are saved over a session -// this means that advanced controller configuration needs to be executed -// each time. this avoids any problems with getting back to a default usage -// or when changing from one controller to another. this way at least something -// works. -cvar_t *in_joystick; -cvar_t *joy_name; -cvar_t *joy_advanced; -cvar_t *joy_advaxisx; -cvar_t *joy_advaxisy; -cvar_t *joy_advaxisz; -cvar_t *joy_advaxisr; -cvar_t *joy_advaxisu; -cvar_t *joy_advaxisv; -cvar_t *joy_forwardthreshold; -cvar_t *joy_sidethreshold; -cvar_t *joy_pitchthreshold; -cvar_t *joy_yawthreshold; -cvar_t *joy_forwardsensitivity; -cvar_t *joy_sidesensitivity; -cvar_t *joy_pitchsensitivity; -cvar_t *joy_yawsensitivity; -cvar_t *joy_wwhack1; -cvar_t *joy_wwhack2; - -int joy_avail, joy_advancedinit, joy_haspov; -DWORD joy_oldbuttonstate, joy_oldpovstate; - -int joy_id; -DWORD joy_flags; -DWORD joy_numbuttons; - -static JOYINFOEX ji; - -/* -=========== -Force_CenterView_f -=========== -*/ -void Force_CenterView_f( void ) -{ - vec3_t viewangles; - - if( !iMouseInUse ) - { - gEngfuncs.GetViewAngles( (float *)viewangles ); - viewangles[PITCH] = 0; - gEngfuncs.SetViewAngles( (float *)viewangles ); - } -} - -/* -=========== -IN_ActivateMouse -=========== -*/ -void DLLEXPORT IN_ActivateMouse( void ) -{ - if( mouseinitialized ) - { - if( mouseparmsvalid ) - restore_spi = SystemParametersInfo( SPI_SETMOUSE, 0, newmouseparms, 0 ); - mouseactive = 1; - } -} - -/* -=========== -IN_DeactivateMouse -=========== -*/ -void DLLEXPORT IN_DeactivateMouse( void ) -{ - if( mouseinitialized ) - { - if( restore_spi ) - SystemParametersInfo( SPI_SETMOUSE, 0, originalmouseparms, 0 ); - mouseactive = 0; - } -} - -/* -=========== -IN_StartupMouse -=========== -*/ -void IN_StartupMouse( void ) -{ - if( gEngfuncs.CheckParm( "-nomouse", NULL ) ) - return; - - mouseinitialized = 1; - mouseparmsvalid = SystemParametersInfo( SPI_GETMOUSE, 0, originalmouseparms, 0 ); - - if( mouseparmsvalid ) - { - if( gEngfuncs.CheckParm( "-noforcemspd", NULL ) ) - newmouseparms[2] = originalmouseparms[2]; - - if( gEngfuncs.CheckParm( "-noforcemaccel", NULL ) ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - } - - if( gEngfuncs.CheckParm( "-noforcemparms", NULL ) ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - newmouseparms[2] = originalmouseparms[2]; - } - } - - mouse_buttons = MOUSE_BUTTON_COUNT; -} - -/* -=========== -IN_Shutdown -=========== -*/ -void IN_Shutdown( void ) -{ - IN_DeactivateMouse (); -} - -/* -=========== -IN_GetMousePos - -Ask for mouse position from engine -=========== -*/ -void IN_GetMousePos( int *mx, int *my ) -{ - gEngfuncs.GetMousePosition( mx, my ); -} - -/* -=========== -IN_ResetMouse - -FIXME: Call through to engine? -=========== -*/ -void IN_ResetMouse( void ) -{ - SetCursorPos ( gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY() ); -} - -/* -=========== -IN_MouseEvent -=========== -*/ -void DLLEXPORT IN_MouseEvent( int mstate ) -{ - int i; - - if( iMouseInUse || g_iVisibleMouse ) - return; - - // perform button actions - for( i = 0; i < mouse_buttons; i++ ) - { - if( ( mstate & ( 1 << i ) ) && - !( mouse_oldbuttonstate & ( 1 << i ) ) ) - { - gEngfuncs.Key_Event( K_MOUSE1 + i, 1 ); - } - - if( !( mstate & ( 1 << i ) ) && - ( mouse_oldbuttonstate & ( 1 << i ) ) ) - { - gEngfuncs.Key_Event( K_MOUSE1 + i, 0 ); - } - } - - mouse_oldbuttonstate = mstate; -} - -/* -=========== -IN_MouseMove -=========== -*/ -void IN_MouseMove( float frametime, usercmd_t *cmd ) -{ - int mx, my; - vec3_t viewangles; - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - //jjb - this disbles normal mouse control if the user is trying to - // move the camera, or if the mouse cursor is visible or if we're in intermission - if( !iMouseInUse && !g_iVisibleMouse && !gHUD.m_iIntermission ) - { - GetCursorPos( ¤t_pos ); - - mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum; - my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum; - - mx_accum = 0; - my_accum = 0; - - if( m_filter->value ) - { - mouse_x = ( mx + old_mouse_x ) * 0.5; - mouse_y = ( my + old_mouse_y ) * 0.5; - } - else - { - mouse_x = mx; - mouse_y = my; - } - - old_mouse_x = mx; - old_mouse_y = my; - - if( gHUD.GetSensitivity() != 0 ) - { - mouse_x *= gHUD.GetSensitivity(); - mouse_y *= gHUD.GetSensitivity(); - } - else - { - mouse_x *= sensitivity->value; - mouse_y *= sensitivity->value; - } - - // add mouse X/Y movement to cmd - if( ( in_strafe.state & 1 ) || ( lookstrafe->value && ( in_mlook.state & 1 ) ) ) - cmd->sidemove += m_side->value * mouse_x; - else - viewangles[YAW] -= m_yaw->value * mouse_x; - - if( ( in_mlook.state & 1 ) && !( in_strafe.state & 1 ) ) - { - viewangles[PITCH] += m_pitch->value * mouse_y; - if( viewangles[PITCH] > cl_pitchdown->value ) - viewangles[PITCH] = cl_pitchdown->value; - if( viewangles[PITCH] < -cl_pitchup->value ) - viewangles[PITCH] = -cl_pitchup->value; - } - else - { - if( ( in_strafe.state & 1 ) && gEngfuncs.IsNoClipping() ) - { - cmd->upmove -= m_forward->value * mouse_y; - } - else - { - cmd->forwardmove -= m_forward->value * mouse_y; - } - } - - // if the mouse has moved, force it to the center, so there's room to move - if( mx || my ) - { - IN_ResetMouse(); - } - } - - gEngfuncs.SetViewAngles( (float *)viewangles ); - -/* -//#define TRACE_TEST -#if defined( TRACE_TEST ) - { - int mx, my; - void V_Move( int mx, int my ); - IN_GetMousePos( &mx, &my ); - V_Move( mx, my ); - } -#endif -*/ -} - -/* -=========== -IN_Accumulate -=========== -*/ -void DLLEXPORT IN_Accumulate( void ) -{ - //only accumulate mouse if we are not moving the camera with the mouse - if( !iMouseInUse && !g_iVisibleMouse ) - { - if( mouseactive ) - { - GetCursorPos( ¤t_pos ); - - mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); - my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); - - // force the mouse to the center, so there's room to move - IN_ResetMouse(); - } - } -} - -/* -=================== -IN_ClearStates -=================== -*/ -void DLLEXPORT IN_ClearStates( void ) -{ - if( !mouseactive ) - return; - - mx_accum = 0; - my_accum = 0; - mouse_oldbuttonstate = 0; -} - -/* -=============== -IN_StartupJoystick -=============== -*/ -void IN_StartupJoystick( void ) -{ - int numdevs; - JOYCAPS jc; - MMRESULT mmr; - - // assume no joystick - joy_avail = 0; - - // abort startup if user requests no joystick - if( gEngfuncs.CheckParm( "-nojoy", NULL ) ) - return; - - // verify joystick driver is present - if( ( numdevs = joyGetNumDevs() ) == 0 ) - { - gEngfuncs.Con_DPrintf( "joystick not found -- driver not present\n\n" ); - return; - } - - // cycle through the joystick ids for the first valid one - for( joy_id = 0; joy_id < numdevs; joy_id++ ) - { - memset( &ji, 0, sizeof(ji) ); - ji.dwSize = sizeof(ji); - ji.dwFlags = JOY_RETURNCENTERED; - - if( ( mmr = joyGetPosEx( joy_id, &ji ) ) == JOYERR_NOERROR ) - break; - } - - // abort startup if we didn't find a valid joystick - if( mmr != JOYERR_NOERROR ) - { - gEngfuncs.Con_DPrintf( "joystick not found -- no valid joysticks (%x)\n\n", mmr ); - return; - } - - // get the capabilities of the selected joystick - // abort startup if command fails - memset( &jc, 0, sizeof(jc) ); - if( ( mmr = joyGetDevCaps( joy_id, &jc, sizeof(jc) ) ) != JOYERR_NOERROR ) - { - gEngfuncs.Con_DPrintf( "joystick not found -- invalid joystick capabilities (%x)\n\n", mmr ); - return; - } - - // save the joystick's number of buttons and POV status - joy_numbuttons = jc.wNumButtons; - joy_haspov = jc.wCaps & JOYCAPS_HASPOV; - - // old button and POV states default to no buttons pressed - joy_oldbuttonstate = joy_oldpovstate = 0; - - // mark the joystick as available and advanced initialization not completed - // this is needed as cvars are not available during initialization - gEngfuncs.Con_Printf( "joystick found\n\n", mmr ); - joy_avail = 1; - joy_advancedinit = 0; -} - -/* -=========== -RawValuePointer -=========== -*/ -PDWORD RawValuePointer( int axis ) -{ - switch( axis ) - { - case JOY_AXIS_X: - return &ji.dwXpos; - case JOY_AXIS_Y: - return &ji.dwYpos; - case JOY_AXIS_Z: - return &ji.dwZpos; - case JOY_AXIS_R: - return &ji.dwRpos; - case JOY_AXIS_U: - return &ji.dwUpos; - case JOY_AXIS_V: - return &ji.dwVpos; - } - // FIX: need to do some kind of error - return &ji.dwXpos; -} - -/* -=========== -Joy_AdvancedUpdate_f -=========== -*/ -void Joy_AdvancedUpdate_f( void ) -{ - // called once by IN_ReadJoystick and by user whenever an update is needed - // cvars are now available - int i; - DWORD dwTemp; - - // initialize all the maps - for( i = 0; i < JOY_MAX_AXES; i++ ) - { - dwAxisMap[i] = AxisNada; - dwControlMap[i] = JOY_ABSOLUTE_AXIS; - pdwRawValue[i] = RawValuePointer(i); - } - - if( joy_advanced->value == 0.0 ) - { - // default joystick initialization - // 2 axes only with joystick control - dwAxisMap[JOY_AXIS_X] = AxisTurn; - // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; - dwAxisMap[JOY_AXIS_Y] = AxisForward; - // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; - } - else - { - if( strcmp( joy_name->string, "joystick" ) != 0 ) - { - // notify user of advanced controller - gEngfuncs.Con_Printf( "\n%s configured\n\n", joy_name->string ); - } - - // advanced initialization here - // data supplied by user via joy_axisn cvars - dwTemp = (DWORD)joy_advaxisx->value; - dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD)joy_advaxisy->value; - dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD)joy_advaxisz->value; - dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD)joy_advaxisr->value; - dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD)joy_advaxisu->value; - dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD)joy_advaxisv->value; - dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; - } - - // compute the axes to collect from DirectInput - joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV; - for( i = 0; i < JOY_MAX_AXES; i++ ) - { - if( dwAxisMap[i] != AxisNada ) - { - joy_flags |= dwAxisFlags[i]; - } - } -} - -/* -=========== -IN_Commands -=========== -*/ -void IN_Commands( void ) -{ - int i, key_index; - DWORD buttonstate, povstate; - - if( !joy_avail ) - { - return; - } - - // loop through the joystick buttons - // key a joystick event or auxillary event for higher number buttons for each state change - buttonstate = ji.dwButtons; - for( i = 0; i < (int)joy_numbuttons; i++ ) - { - if( ( buttonstate & ( 1 << i ) ) && !( joy_oldbuttonstate & ( 1 << i ) ) ) - { - key_index = ( i < 4 ) ? K_JOY1 : K_AUX1; - gEngfuncs.Key_Event( key_index + i, 1 ); - } - - if( !( buttonstate & ( 1 << i ) ) && ( joy_oldbuttonstate & ( 1 << i ) ) ) - { - key_index = ( i < 4 ) ? K_JOY1 : K_AUX1; - gEngfuncs.Key_Event( key_index + i, 0 ); - } - } - joy_oldbuttonstate = buttonstate; - - if( joy_haspov ) - { - // convert POV information into 4 bits of state information - // this avoids any potential problems related to moving from one - // direction to another without going through the center position - povstate = 0; - if( ji.dwPOV != JOY_POVCENTERED ) - { - if( ji.dwPOV == JOY_POVFORWARD ) - povstate |= 0x01; - if( ji.dwPOV == JOY_POVRIGHT ) - povstate |= 0x02; - if( ji.dwPOV == JOY_POVBACKWARD ) - povstate |= 0x04; - if( ji.dwPOV == JOY_POVLEFT ) - povstate |= 0x08; - } - // determine which bits have changed and key an auxillary event for each change - for( i = 0; i < 4; i++ ) - { - if( ( povstate & ( 1 << i ) ) && !( joy_oldpovstate & ( 1 << i ) ) ) - { - gEngfuncs.Key_Event( K_AUX29 + i, 1 ); - } - - if( !( povstate & ( 1 << i ) ) && ( joy_oldpovstate & ( 1 << i ) ) ) - { - gEngfuncs.Key_Event( K_AUX29 + i, 0 ); - } - } - joy_oldpovstate = povstate; - } -} - -/* -=============== -IN_ReadJoystick -=============== -*/ -int IN_ReadJoystick( void ) -{ - memset( &ji, 0, sizeof(ji) ); - ji.dwSize = sizeof(ji); - ji.dwFlags = joy_flags; - - if( joyGetPosEx( joy_id, &ji ) == JOYERR_NOERROR ) - { - // this is a hack -- there is a bug in the Logitech WingMan Warrior DirectInput Driver - // rather than having 32768 be the zero point, they have the zero point at 32668 - // go figure -- anyway, now we get the full resolution out of the device - if( joy_wwhack1->value != 0.0 ) - { - ji.dwUpos += 100; - } - return 1; - } - else - { - // read error occurred - // turning off the joystick seems too harsh for 1 read error,\ - // but what should be done? - // Con_Printf( "IN_ReadJoystick: no response\n" ); - // joy_avail = 0; - return 0; - } -} - -/* -=========== -IN_JoyMove -=========== -*/ -void IN_JoyMove( float frametime, usercmd_t *cmd ) -{ - float speed, aspeed; - float fAxisValue, fTemp; - int i; - vec3_t viewangles; - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - // complete initialization if first time in - // this is needed as cvars are not available at initialization time - if( joy_advancedinit != 1 ) - { - Joy_AdvancedUpdate_f(); - joy_advancedinit = 1; - } - - // verify joystick is available and that the user wants to use it - if( !joy_avail || !in_joystick->value ) - { - return; - } - - // collect the joystick data, if possible - if( IN_ReadJoystick () != 1 ) - { - return; - } - - if( in_speed.state & 1 ) - speed = cl_movespeedkey->value; - else - speed = 1; - - aspeed = speed * frametime; - - // loop through the axes - for( i = 0; i < JOY_MAX_AXES; i++ ) - { - // get the floating point zero-centered, potentially-inverted data for the current axis - fAxisValue = (float) *pdwRawValue[i]; - // move centerpoint to zero - fAxisValue -= 32768.0; - - if( joy_wwhack2->value != 0.0 ) - { - if( dwAxisMap[i] == AxisTurn ) - { - // this is a special formula for the Logitech WingMan Warrior - // y=ax^b; where a = 300 and b = 1.3 - // also x values are in increments of 800 (so this is factored out) - // then bounds check result to level out excessively high spin rates - fTemp = 300.0 * pow( abs( fAxisValue ) / 800.0, 1.3 ); - if( fTemp > 14000.0 ) - fTemp = 14000.0; - // restore direction information - fAxisValue = ( fAxisValue > 0.0 ) ? fTemp : -fTemp; - } - } - - // convert range from -32768..32767 to -1..1 - fAxisValue /= 32768.0; - - switch( dwAxisMap[i] ) - { - case AxisForward: - if( ( joy_advanced->value == 0.0 ) && ( in_jlook.state & 1 ) ) - { - // user wants forward control to become look control - if( fabs( fAxisValue ) > joy_pitchthreshold->value ) - { - // if mouse invert is on, invert the joystick pitch value - // only absolute control support here (joy_advanced is 0) - if( m_pitch->value < 0.0 ) - { - viewangles[PITCH] -= ( fAxisValue * joy_pitchsensitivity->value ) * aspeed * cl_pitchspeed->value; - } - else - { - viewangles[PITCH] += ( fAxisValue * joy_pitchsensitivity->value ) * aspeed * cl_pitchspeed->value; - } - } - } - else - { - // user wants forward control to be forward control - if( fabs( fAxisValue ) > joy_forwardthreshold->value ) - { - cmd->forwardmove += ( fAxisValue * joy_forwardsensitivity->value ) * speed * cl_forwardspeed->value; - } - } - break; - case AxisSide: - if( fabs( fAxisValue ) > joy_sidethreshold->value ) - { - cmd->sidemove += ( fAxisValue * joy_sidesensitivity->value ) * speed * cl_sidespeed->value; - } - break; - case AxisTurn: - if( ( in_strafe.state & 1 ) || ( lookstrafe->value && ( in_jlook.state & 1 ) ) ) - { - // user wants turn control to become side control - if( fabs( fAxisValue ) > joy_sidethreshold->value ) - { - cmd->sidemove -= ( fAxisValue * joy_sidesensitivity->value ) * speed * cl_sidespeed->value; - } - } - else - { - // user wants turn control to be turn control - if( fabs( fAxisValue ) > joy_yawthreshold->value ) - { - if( dwControlMap[i] == JOY_ABSOLUTE_AXIS ) - { - viewangles[YAW] += ( fAxisValue * joy_yawsensitivity->value ) * aspeed * cl_yawspeed->value; - } - else - { - viewangles[YAW] += ( fAxisValue * joy_yawsensitivity->value ) * speed * 180.0; - } - } - } - break; - case AxisLook: - if( in_jlook.state & 1 ) - { - if( fabs( fAxisValue ) > joy_pitchthreshold->value ) - { - // pitch movement detected and pitch movement desired by user - if( dwControlMap[i] == JOY_ABSOLUTE_AXIS ) - { - viewangles[PITCH] += ( fAxisValue * joy_pitchsensitivity->value ) * aspeed * cl_pitchspeed->value; - } - else - { - viewangles[PITCH] += ( fAxisValue * joy_pitchsensitivity->value ) * speed * 180.0; - } - } - } - break; - default: - break; - } - } - - // bounds check pitch - if( viewangles[PITCH] > cl_pitchdown->value ) - viewangles[PITCH] = cl_pitchdown->value; - if( viewangles[PITCH] < -cl_pitchup->value ) - viewangles[PITCH] = -cl_pitchup->value; - - gEngfuncs.SetViewAngles( (float *)viewangles ); -} - -/* -=========== -IN_Move -=========== -*/ -void IN_Move( float frametime, usercmd_t *cmd ) -{ - if( !iMouseInUse && mouseactive ) - { - IN_MouseMove( frametime, cmd ); - } - - IN_JoyMove( frametime, cmd ); -} - -/* -=========== -IN_Init -=========== -*/ -void IN_Init( void ) -{ - m_filter = gEngfuncs.pfnRegisterVariable( "m_filter","0", FCVAR_ARCHIVE ); - sensitivity = gEngfuncs.pfnRegisterVariable( "sensitivity","3", FCVAR_ARCHIVE ); // user mouse sensitivity setting. - - in_joystick = gEngfuncs.pfnRegisterVariable( "joystick","0", FCVAR_ARCHIVE ); - joy_name = gEngfuncs.pfnRegisterVariable( "joyname", "joystick", 0 ); - joy_advanced = gEngfuncs.pfnRegisterVariable( "joyadvanced", "0", 0 ); - joy_advaxisx = gEngfuncs.pfnRegisterVariable( "joyadvaxisx", "0", 0 ); - joy_advaxisy = gEngfuncs.pfnRegisterVariable( "joyadvaxisy", "0", 0 ); - joy_advaxisz = gEngfuncs.pfnRegisterVariable( "joyadvaxisz", "0", 0 ); - joy_advaxisr = gEngfuncs.pfnRegisterVariable( "joyadvaxisr", "0", 0 ); - joy_advaxisu = gEngfuncs.pfnRegisterVariable( "joyadvaxisu", "0", 0 ); - joy_advaxisv = gEngfuncs.pfnRegisterVariable( "joyadvaxisv", "0", 0 ); - joy_forwardthreshold = gEngfuncs.pfnRegisterVariable( "joyforwardthreshold", "0.15", 0 ); - joy_sidethreshold = gEngfuncs.pfnRegisterVariable( "joysidethreshold", "0.15", 0 ); - joy_pitchthreshold = gEngfuncs.pfnRegisterVariable( "joypitchthreshold", "0.15", 0 ); - joy_yawthreshold = gEngfuncs.pfnRegisterVariable( "joyyawthreshold", "0.15", 0 ); - joy_forwardsensitivity = gEngfuncs.pfnRegisterVariable( "joyforwardsensitivity", "-1.0", 0 ); - joy_sidesensitivity = gEngfuncs.pfnRegisterVariable( "joysidesensitivity", "-1.0", 0 ); - joy_pitchsensitivity = gEngfuncs.pfnRegisterVariable( "joypitchsensitivity", "1.0", 0 ); - joy_yawsensitivity = gEngfuncs.pfnRegisterVariable( "joyyawsensitivity", "-1.0", 0 ); - joy_wwhack1 = gEngfuncs.pfnRegisterVariable( "joywwhack1", "0.0", 0 ); - joy_wwhack2 = gEngfuncs.pfnRegisterVariable( "joywwhack2", "0.0", 0 ); - - gEngfuncs.pfnAddCommand ("force_centerview", Force_CenterView_f); - gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); - - IN_StartupMouse (); - IN_StartupJoystick (); -} From 1d8d1b5d2e7d804e41c844642bb541cc17be4001 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sun, 3 Dec 2017 23:52:35 +0300 Subject: [PATCH 117/211] Use mouse input backend depending on the current engine --- cl_dll/CMakeLists.txt | 11 ++--- cl_dll/cl_dll.h | 3 ++ cl_dll/hud.h | 4 +- cl_dll/input_goldsource.cpp | 43 +++++++++---------- cl_dll/input_mouse.cpp | 82 +++++++++++++++++++++++++++++++++++++ cl_dll/input_mouse.h | 77 ++++++++++++++++++++++++++++++++++ cl_dll/input_xash3d.cpp | 41 +++++++------------ 7 files changed, 204 insertions(+), 57 deletions(-) create mode 100644 cl_dll/input_mouse.cpp create mode 100644 cl_dll/input_mouse.h diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 7bd04f77..776f9bd9 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -27,7 +27,7 @@ set (CLDLL_LIBRARY client) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w") if (GOLDSOURCE_SUPPORT) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lSDL2 -Wl,--no-undefined") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT -lSDL2 -Wl,--no-undefined") endif() set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") @@ -73,6 +73,9 @@ set (CLDLL_SOURCES hud_update.cpp in_camera.cpp input.cpp + input_goldsource.cpp + input_mouse.cpp + input_xash3d.cpp menu.cpp message.cpp overview.cpp @@ -93,12 +96,6 @@ set (CLDLL_SOURCES scoreboard.cpp MOTD.cpp) -if (GOLDSOURCE_SUPPORT) - set (CLDLL_SOURCES "${CLDLL_SOURCES}" input_goldsource.cpp) -else() - set (CLDLL_SOURCES "${CLDLL_SOURCES}" input_xash3d.cpp) -endif() - include_directories (. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public) if(USE_VOICEMGR) diff --git a/cl_dll/cl_dll.h b/cl_dll/cl_dll.h index 24d1874b..0acd6860 100644 --- a/cl_dll/cl_dll.h +++ b/cl_dll/cl_dll.h @@ -25,6 +25,8 @@ // - Drawing the HUD graphics every frame // - Handling the custum HUD-update packets // +#ifndef CL_DLL_H +#define CL_DLL_H typedef unsigned char byte; typedef unsigned short word; typedef float vec_t; @@ -48,3 +50,4 @@ typedef int ( *pfnUserMsgHook )( const char *pszName, int iSize, void *pbuf ); extern cl_enginefunc_t gEngfuncs; #include "../engine/mobility_int.h" extern mobile_engfuncs_t *gMobileEngfuncs; +#endif diff --git a/cl_dll/hud.h b/cl_dll/hud.h index ab179bbb..1970753d 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -19,7 +19,8 @@ // // CHud handles the message, calculation, and drawing the HUD // - +#ifndef HUD_H +#define HUD_H #define RGB_YELLOWISH 0x00FFA000 //255,160,0 #define RGB_REDISH 0x00FF1010 //255,160,0 #define RGB_GREENISH 0x0000A000 //0,160,0 @@ -677,3 +678,4 @@ extern int g_iTeamNumber; extern int g_iUser1; extern int g_iUser2; extern int g_iUser3; +#endif diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index 70cd23c5..5c2b0381 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -8,20 +8,20 @@ // in_win.c -- windows 95 mouse and joystick code // 02/21/97 JCB Added extended DirectInput code to support external controllers. -//#include "port.h" +#include "input_mouse.h" + +#ifdef SUPPORT_GOLDSOURCE_INPUT #include "hud.h" #include "cl_util.h" #include "camera.h" #include "kbutton.h" #include "cvardef.h" -#include "usercmd.h" #include "const.h" #include "camera.h" #include "in_defs.h" #include "keydefs.h" #include "view.h" -//#include "Exports.h" #ifndef _WIN32 #define USE_SDL2 @@ -79,7 +79,7 @@ bool isMouseRelative = false; extern globalvars_t *gpGlobals; #endif -Vector dead_viewangles(0, 0, 0); +extern Vector dead_viewangles; void V_StopPitchDrift( void ) { @@ -88,7 +88,7 @@ void V_StopPitchDrift( void ) // mouse variables cvar_t *m_filter; -cvar_t *sensitivity; +extern cvar_t *sensitivity; // Custom mouse acceleration (0 disable, 1 to enable, 2 enable with separate yaw/pitch rescale) static cvar_t *m_customaccel; @@ -106,16 +106,11 @@ static cvar_t *m_customaccel_exponent; static cvar_t *m_mousethread_sleep; #endif -int mouse_buttons; -int mouse_oldbuttonstate; -POINT current_pos; -int old_mouse_x, old_mouse_y, mx_accum, my_accum; float mouse_x, mouse_y; static int restore_spi; static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; static int mouseactive = 0; -int mouseinitialized; static int mouseparmsvalid; static int mouseshowtoggle = 1; @@ -158,7 +153,7 @@ SDL_GameController *s_pJoystick = NULL; // each time. this avoids any problems with getting back to a default usage // or when changing from one controller to another. this way at least something // works. -cvar_t *in_joystick; +extern cvar_t *in_joystick; cvar_t *joy_name; cvar_t *joy_advanced; cvar_t *joy_advaxisx; @@ -348,7 +343,7 @@ void IN_ResetMouse( void ); IN_ActivateMouse =========== */ -extern "C" void DLLEXPORT IN_ActivateMouse (void) +void GoldSourceInput::IN_ActivateMouse (void) { if (mouseinitialized) { @@ -376,7 +371,7 @@ extern "C" void DLLEXPORT IN_ActivateMouse (void) IN_DeactivateMouse =========== */ -extern "C" void DLLEXPORT IN_DeactivateMouse (void) +void GoldSourceInput::IN_DeactivateMouse (void) { if (mouseinitialized) { @@ -400,7 +395,7 @@ extern "C" void DLLEXPORT IN_DeactivateMouse (void) IN_StartupMouse =========== */ -void IN_StartupMouse (void) +void GoldSourceInput::IN_StartupMouse (void) { if ( gEngfuncs.CheckParm ("-nomouse", NULL ) ) return; @@ -437,7 +432,7 @@ void IN_StartupMouse (void) IN_Shutdown =========== */ -void IN_Shutdown (void) +void GoldSourceInput::IN_Shutdown (void) { IN_DeactivateMouse (); @@ -521,7 +516,7 @@ void IN_ResetMouse( void ) IN_MouseEvent =========== */ -extern "C" void DLLEXPORT IN_MouseEvent (int mstate) +void GoldSourceInput::IN_MouseEvent (int mstate) { int i; @@ -596,7 +591,7 @@ void IN_ScaleMouse( float *x, float *y ) } } -void IN_GetMouseDelta( int *pOutX, int *pOutY) +void GoldSourceInput::IN_GetMouseDelta( int *pOutX, int *pOutY) { bool active = mouseactive && !iVisibleMouse; int mx, my; @@ -715,7 +710,7 @@ void IN_GetMouseDelta( int *pOutX, int *pOutY) IN_MouseMove =========== */ -void IN_MouseMove ( float frametime, usercmd_t *cmd) +void GoldSourceInput::IN_MouseMove ( float frametime, usercmd_t *cmd) { int mx, my; vec3_t viewangles; @@ -797,7 +792,7 @@ void IN_MouseMove ( float frametime, usercmd_t *cmd) IN_Accumulate =========== */ -extern "C" void DLLEXPORT IN_Accumulate (void) +void GoldSourceInput::IN_Accumulate (void) { //only accumulate mouse if we are not moving the camera with the mouse if ( !iMouseInUse && !iVisibleMouse) @@ -850,7 +845,7 @@ extern "C" void DLLEXPORT IN_Accumulate (void) IN_ClearStates =================== */ -extern "C" void DLLEXPORT IN_ClearStates (void) +void GoldSourceInput::IN_ClearStates (void) { if ( !mouseactive ) return; @@ -999,7 +994,7 @@ void Joy_AdvancedUpdate_f (void) IN_Commands =========== */ -void IN_Commands (void) +void GoldSourceInput::IN_Commands (void) { int i, key_index; @@ -1274,7 +1269,7 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd ) IN_Move =========== */ -void IN_Move ( float frametime, usercmd_t *cmd) +void GoldSourceInput::IN_Move ( float frametime, usercmd_t *cmd) { if ( !iMouseInUse && mouseactive ) { @@ -1289,7 +1284,7 @@ void IN_Move ( float frametime, usercmd_t *cmd) IN_Init =========== */ -void IN_Init (void) +void GoldSourceInput::IN_Init (void) { m_filter = gEngfuncs.pfnRegisterVariable ( "m_filter","0", FCVAR_ARCHIVE ); sensitivity = gEngfuncs.pfnRegisterVariable ( "sensitivity","3", FCVAR_ARCHIVE ); // user mouse sensitivity setting. @@ -1355,3 +1350,5 @@ void IN_Init (void) IN_StartupMouse (); IN_StartupJoystick (); } + +#endif diff --git a/cl_dll/input_mouse.cpp b/cl_dll/input_mouse.cpp new file mode 100644 index 00000000..724824cd --- /dev/null +++ b/cl_dll/input_mouse.cpp @@ -0,0 +1,82 @@ +#include "input_mouse.h" +#include "exportdef.h" +#include "hud.h" + +// shared between backends +Vector dead_viewangles(0, 0, 0); +cvar_t *sensitivity; +cvar_t *in_joystick; + +FWGSInput fwgsInput; + +#ifdef SUPPORT_GOLDSOURCE_INPUT +GoldSourceInput goldSourceInput; +AbstractInput* currentInput = &goldSourceInput; +#else +AbstractInput* currentInput = &fwgsInput; +#endif +extern "C" void DLLEXPORT IN_ClientMoveEvent( float forwardmove, float sidemove ) +{ + currentInput->IN_ClientMoveEvent(forwardmove, sidemove); +} + +extern "C" void DLLEXPORT IN_ClientLookEvent( float relyaw, float relpitch ) +{ + currentInput->IN_ClientLookEvent(relyaw, relpitch); +} + +void IN_Move( float frametime, usercmd_t *cmd ) +{ + currentInput->IN_Move(frametime, cmd); +} + +extern "C" void DLLEXPORT IN_MouseEvent( int mstate ) +{ + currentInput->IN_MouseEvent(mstate); +} + +extern "C" void DLLEXPORT IN_ClearStates( void ) +{ + currentInput->IN_ClearStates(); +} + +extern "C" void DLLEXPORT IN_ActivateMouse( void ) +{ + currentInput->IN_ActivateMouse(); +} + +extern "C" void DLLEXPORT IN_DeactivateMouse( void ) +{ + currentInput->IN_DeactivateMouse(); +} + +extern "C" void DLLEXPORT IN_Accumulate( void ) +{ + currentInput->IN_Accumulate(); +} + +void IN_Commands( void ) +{ + currentInput->IN_Commands(); +} + +void IN_Shutdown( void ) +{ + currentInput->IN_Shutdown(); +} + +void IN_Init( void ) +{ +#ifdef SUPPORT_GOLDSOURCE_INPUT + if (gMobileEngfuncs) { + gEngfuncs.Con_Printf( "FWGS Xash3D input is in use\n" ); + currentInput = &fwgsInput; + } else { + gEngfuncs.Con_Printf( "GoldSource input is in use\n" ); + currentInput = &goldSourceInput; + } +#else + currentInput = &fwgsInput; +#endif + currentInput->IN_Init(); +} diff --git a/cl_dll/input_mouse.h b/cl_dll/input_mouse.h new file mode 100644 index 00000000..6ddf54db --- /dev/null +++ b/cl_dll/input_mouse.h @@ -0,0 +1,77 @@ +#ifndef INPUT_MOUSE_H +#define INPUT_MOUSE_H +#include "cl_dll.h" +#include "usercmd.h" +#include "in_defs.h" + +class AbstractInput +{ +public: + virtual void IN_ClientMoveEvent( float forwardmove, float sidemove ) = 0; + virtual void IN_ClientLookEvent( float relyaw, float relpitch ) = 0; + virtual void IN_Move( float frametime, usercmd_t *cmd ) = 0; + virtual void IN_MouseEvent( int mstate ) = 0; + virtual void IN_ClearStates( void ) = 0; + virtual void IN_ActivateMouse( void ) = 0; + virtual void IN_DeactivateMouse( void ) = 0; + virtual void IN_Accumulate( void ) = 0; + virtual void IN_Commands( void ) = 0; + virtual void IN_Shutdown( void ) = 0; + virtual void IN_Init( void ) = 0; +}; + +class FWGSInput : public AbstractInput +{ +public: + virtual void IN_ClientMoveEvent( float forwardmove, float sidemove ); + virtual void IN_ClientLookEvent( float relyaw, float relpitch ); + virtual void IN_Move( float frametime, usercmd_t *cmd ); + virtual void IN_MouseEvent( int mstate ); + virtual void IN_ClearStates( void ); + virtual void IN_ActivateMouse( void ); + virtual void IN_DeactivateMouse( void ); + virtual void IN_Accumulate( void ); + virtual void IN_Commands( void ); + virtual void IN_Shutdown( void ); + virtual void IN_Init( void ); + +protected: + float ac_forwardmove; + float ac_sidemove; + int ac_movecount; + float rel_yaw; + float rel_pitch; +}; + +// No need for goldsource input support on the platforms that are not supported by GoldSource. +#if defined(GOLDSOURCE_SUPPORT) && (defined(_WIN32) || defined(__linux__) || defined(__APPLE__)) && (defined(__i386) || defined(_M_IX86)) +#define SUPPORT_GOLDSOURCE_INPUT +class GoldSourceInput : public AbstractInput +{ +public: + virtual void IN_ClientMoveEvent( float forwardmove, float sidemove ) {} + virtual void IN_ClientLookEvent( float relyaw, float relpitch ) {} + virtual void IN_Move( float frametime, usercmd_t *cmd ); + virtual void IN_MouseEvent( int mstate ); + virtual void IN_ClearStates( void ); + virtual void IN_ActivateMouse( void ); + virtual void IN_DeactivateMouse( void ); + virtual void IN_Accumulate( void ); + virtual void IN_Commands( void ); + virtual void IN_Shutdown( void ); + virtual void IN_Init( void ); + +protected: + void IN_GetMouseDelta( int *pOutX, int *pOutY); + void IN_MouseMove ( float frametime, usercmd_t *cmd); + void IN_StartupMouse (void); + + int mouse_buttons; + int mouse_oldbuttonstate; + POINT current_pos; + int old_mouse_x, old_mouse_y, mx_accum, my_accum; + int mouseinitialized; +}; +#endif + +#endif diff --git a/cl_dll/input_xash3d.cpp b/cl_dll/input_xash3d.cpp index 63cdfbeb..2ff572ee 100644 --- a/cl_dll/input_xash3d.cpp +++ b/cl_dll/input_xash3d.cpp @@ -3,14 +3,9 @@ #include "cvardef.h" #include "kbutton.h" #include "keydefs.h" -cvar_t *sensitivity; -cvar_t *in_joystick; -#define PITCH 0 -#define YAW 1 -#define ROLL 2 - -extern "C" void DLLEXPORT IN_ClientMoveEvent( float forwardmove, float sidemove ); -extern "C" void DLLEXPORT IN_ClientLookEvent( float relyaw, float relpitch ); +#include "input_mouse.h" +extern cvar_t *sensitivity; +extern cvar_t *in_joystick; extern kbutton_t in_strafe; extern kbutton_t in_mlook; @@ -37,12 +32,6 @@ extern cvar_t *cl_movespeedkey; cvar_t *cl_laddermode; -float ac_forwardmove; -float ac_sidemove; -int ac_movecount; -float rel_yaw; -float rel_pitch; - #define F 1U<<0 // Forward #define B 1U<<1 // Back #define L 1U<<2 // Left @@ -55,7 +44,7 @@ float rel_pitch; #define IMPULSE_UP 4 int CL_IsDead( void ); -Vector dead_viewangles(0, 0, 0); +extern Vector dead_viewangles; void IN_ToggleButtons( float forwardmove, float sidemove ) { @@ -135,7 +124,7 @@ void IN_ToggleButtons( float forwardmove, float sidemove ) } } -void IN_ClientMoveEvent( float forwardmove, float sidemove ) +void FWGSInput::IN_ClientMoveEvent( float forwardmove, float sidemove ) { //gEngfuncs.Con_Printf("IN_MoveEvent\n"); @@ -144,14 +133,14 @@ void IN_ClientMoveEvent( float forwardmove, float sidemove ) ac_movecount++; } -void IN_ClientLookEvent( float relyaw, float relpitch ) +void FWGSInput::IN_ClientLookEvent( float relyaw, float relpitch ) { rel_yaw += relyaw; rel_pitch += relpitch; } // Rotate camera and add move values to usercmd -void IN_Move( float frametime, usercmd_t *cmd ) +void FWGSInput::IN_Move( float frametime, usercmd_t *cmd ) { Vector viewangles; bool fLadder = false; @@ -235,7 +224,7 @@ void IN_Move( float frametime, usercmd_t *cmd ) ac_movecount = 0; } -extern "C" void DLLEXPORT IN_MouseEvent( int mstate ) +void FWGSInput::IN_MouseEvent( int mstate ) { static int mouse_oldbuttonstate; // perform button actions @@ -257,37 +246,37 @@ extern "C" void DLLEXPORT IN_MouseEvent( int mstate ) // Stubs -extern "C" void DLLEXPORT IN_ClearStates( void ) +void FWGSInput::IN_ClearStates( void ) { //gEngfuncs.Con_Printf( "IN_ClearStates\n" ); } -extern "C" void DLLEXPORT IN_ActivateMouse( void ) +void FWGSInput::IN_ActivateMouse( void ) { //gEngfuncs.Con_Printf( "IN_ActivateMouse\n" ); } -extern "C" void DLLEXPORT IN_DeactivateMouse( void ) +void FWGSInput::IN_DeactivateMouse( void ) { //gEngfuncs.Con_Printf( "IN_DeactivateMouse\n" ); } -extern "C" void DLLEXPORT IN_Accumulate( void ) +void FWGSInput::IN_Accumulate( void ) { //gEngfuncs.Con_Printf( "IN_Accumulate\n" ); } -void IN_Commands( void ) +void FWGSInput::IN_Commands( void ) { //gEngfuncs.Con_Printf( "IN_Commands\n" ); } -void IN_Shutdown( void ) +void FWGSInput::IN_Shutdown( void ) { } // Register cvars and reset data -void IN_Init( void ) +void FWGSInput::IN_Init( void ) { sensitivity = gEngfuncs.pfnRegisterVariable( "sensitivity", "3", FCVAR_ARCHIVE ); in_joystick = gEngfuncs.pfnRegisterVariable( "joystick", "0", FCVAR_ARCHIVE ); From 84e720eadcfa27434ee65335cb87c8e41a63a92f Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Mon, 4 Dec 2017 15:42:45 +0300 Subject: [PATCH 118/211] Add new input files and goldsource support flag to client makefiles --- cl_dll/Android.mk | 7 +++++++ cl_dll/Makefile | 11 ++++++++--- cl_dll/cl_dll.dsp | 14 +++++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/cl_dll/Android.mk b/cl_dll/Android.mk index a79b6363..29aee174 100755 --- a/cl_dll/Android.mk +++ b/cl_dll/Android.mk @@ -68,6 +68,8 @@ SRCS+=./hud_spectator.cpp SRCS+=./hud_update.cpp SRCS+=./in_camera.cpp SRCS+=./input.cpp +SRCS+=./input_goldsource.cpp +SRCS+=./input_mouse.cpp #SRCS+=./inputw32.cpp SRCS+=./menu.cpp SRCS+=./message.cpp @@ -100,6 +102,11 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \ $(LOCAL_PATH)/../pm_shared LOCAL_CFLAGS += $(DEFINES) $(INCLUDES) +ifeq ($(GOLDSOURCE_SUPPORT),1) + DEFINES += -DGOLDSOURCE_SUPPORT + LOCAL_LDLIBS += -lSDL2 +endif + LOCAL_SRC_FILES := $(SRCS) $(SRCS_C) include $(BUILD_SHARED_LIBRARY) diff --git a/cl_dll/Makefile b/cl_dll/Makefile index 983b61c0..16427f8f 100644 --- a/cl_dll/Makefile +++ b/cl_dll/Makefile @@ -45,7 +45,8 @@ SRCS+=./hud_spectator.cpp SRCS+=./hud_update.cpp SRCS+=./in_camera.cpp SRCS+=./input.cpp -#SRCS+=./inputw32.cpp +SRCS+=./input_mouse.cpp +SRCS+=./input_goldsource.cpp SRCS+=./menu.cpp SRCS+=./message.cpp SRCS+=./overview.cpp @@ -72,9 +73,13 @@ CFLAGS = -m32 OBJS = $(SRCS:.cpp=.o) $(SRCS_C:.c=.o) LIBS=-lm +ifeq ($(GOLDSOURCE_SUPPORT),1) + DEFINES += -DGOLDSOURCE_SUPPORT + LIBS += -lSDL2 +endif ifeq ($(shell uname -s),Linux) - LIBS=$(LIBS) -ldl + LIBS += -ldl endif %.o : %.c @@ -83,7 +88,7 @@ endif %.o : %.cpp $(CXX) $(CFLAGS) $(INCLUDES) $(DEFINES) -fPIC -c $< -o $@ client.so : $(OBJS) - $(CXX) $(OBJS) -o client.so -shared -Wl,--no-undefined -fPIC $(LIBS) + $(CXX) $(CFLAGS) $(OBJS) -o client.so -shared -Wl,--no-undefined -fPIC $(LIBS) clean: $(RM) $(OBJS) diff --git a/cl_dll/cl_dll.dsp b/cl_dll/cl_dll.dsp index 6864326b..e8ae7d15 100644 --- a/cl_dll/cl_dll.dsp +++ b/cl_dll/cl_dll.dsp @@ -300,7 +300,15 @@ SOURCE=.\input.cpp # End Source File # Begin Source File -SOURCE=.\inputw32.cpp +SOURCE=.\input_goldsource.cpp +# End Source File +# Begin Source File + +SOURCE=.\input_mouse.cpp +# End Source File +# Begin Source File + +SOURCE=.\input_xash3d.cpp # End Source File # Begin Source File @@ -513,6 +521,10 @@ SOURCE=.\in_defs.h # End Source File # Begin Source File +SOURCE=.\input_mouse.h +# End Source File +# Begin Source File + SOURCE=..\common\itrackeruser.h # End Source File # Begin Source File From d904505f6a991532fd2eedff4e98b683347f71cd Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 6 Dec 2017 19:19:27 +0300 Subject: [PATCH 119/211] Get vgui back for goldsource fullscreen support --- cl_dll/CMakeLists.txt | 9 ++++-- cl_dll/cdll_int.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 776f9bd9..2ad46949 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -27,7 +27,12 @@ set (CLDLL_LIBRARY client) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w") if (GOLDSOURCE_SUPPORT) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT -lSDL2 -Wl,--no-undefined") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT -L${CMAKE_CURRENT_SOURCE_DIR}/.. -lSDL2 -Wl,--no-undefined") + if (APPLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -l:vgui.dylib") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -l:vgui.so") + endif() endif() set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") @@ -96,7 +101,7 @@ set (CLDLL_SOURCES scoreboard.cpp MOTD.cpp) -include_directories (. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public) +include_directories (. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public ../utils/vgui/include) if(USE_VOICEMGR) #set(CLDLL_SOURCES diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index d71659e9..00496ea8 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -23,6 +23,13 @@ #include "netadr.h" #include "parsemsg.h" +#if defined(GOLDSOURCE_SUPPORT) && (defined(_WIN32) || defined(__linux__) || defined(__APPLE__)) && (defined(__i386) || defined(_M_IX86)) +#define USE_VGUI_FOR_GOLDSOURCE_SUPPORT +#include "VGUI_Panel.h" +#include "VGUI_BorderLayout.h" +#include "VGUI_App.h" +#endif + extern "C" { #include "pm_shared.h" @@ -177,6 +184,46 @@ int *HUD_GetRect( void ) return extent; } +#ifdef USE_VGUI_FOR_GOLDSOURCE_SUPPORT +class TeamFortressViewport : public vgui::Panel +{ +public: + TeamFortressViewport(int x,int y,int wide,int tall); + void Initialize( void ); + + virtual void paintBackground(); + void *operator new( size_t stAllocateBlock ); +}; + +static TeamFortressViewport* gViewPort = NULL; + +TeamFortressViewport::TeamFortressViewport(int x, int y, int wide, int tall) +{ + gViewPort = this; + Initialize(); +} + +void TeamFortressViewport::Initialize() +{ + vgui::App::getInstance()->setCursorOveride( vgui::App::getInstance()->getScheme()->getCursor(vgui::Scheme::scu_none) ); +} + +void TeamFortressViewport::paintBackground() +{ + int wide, tall; + getParent()->getSize( wide, tall ); + setSize( wide, tall ); + gEngfuncs.VGui_ViewportPaintBackground(HUD_GetRect()); +} + +void *TeamFortressViewport::operator new( size_t stAllocateBlock ) +{ + void *mem = ::operator new( stAllocateBlock ); + memset( mem, 0, stAllocateBlock ); + return mem; +} +#endif + /* ========================== HUD_VidInit @@ -190,7 +237,21 @@ so the HUD can reinitialize itself. int DLLEXPORT HUD_VidInit( void ) { gHUD.VidInit(); +#ifdef USE_VGUI_FOR_GOLDSOURCE_SUPPORT + vgui::Panel* root=(vgui::Panel*)gEngfuncs.VGui_GetPanel(); + root->setBgColor(128,128,0,0); + root->setLayout(new vgui::BorderLayout(0)); + if (gViewPort != NULL) + { + gViewPort->Initialize(); + } + else + { + gViewPort = new TeamFortressViewport(0,0,root->getWide(),root->getTall()); + gViewPort->setParent(root); + } +#endif return 1; } @@ -270,7 +331,10 @@ Called by engine every frame that client .dll is loaded */ void DLLEXPORT HUD_Frame( double time ) -{ gEngfuncs.VGui_ViewportPaintBackground(HUD_GetRect()); +{ +#ifndef USE_VGUI_FOR_GOLDSOURCE_SUPPORT + gEngfuncs.VGui_ViewportPaintBackground(HUD_GetRect()); +#endif } /* From 51bf51a840649165078226661ef790c0ed3971e4 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 6 Dec 2017 20:38:14 +0300 Subject: [PATCH 120/211] Provide vgui stub to avoid dependency of client of vgui lib --- cl_dll/CMakeLists.txt | 7 +- cl_dll/cdll_int.cpp | 37 ++-- utils/false_vgui/include/VGUI.h | 108 ++++++++++ utils/false_vgui/include/VGUI_App.h | 130 ++++++++++++ utils/false_vgui/include/VGUI_Bitmap.h | 37 ++++ utils/false_vgui/include/VGUI_Color.h | 44 +++++ utils/false_vgui/include/VGUI_Cursor.h | 57 ++++++ utils/false_vgui/include/VGUI_Dar.h | 194 ++++++++++++++++++ utils/false_vgui/include/VGUI_Image.h | 62 ++++++ utils/false_vgui/include/VGUI_KeyCode.h | 126 ++++++++++++ utils/false_vgui/include/VGUI_MouseCode.h | 24 +++ utils/false_vgui/include/VGUI_Panel.h | 229 ++++++++++++++++++++++ utils/false_vgui/include/VGUI_Scheme.h | 82 ++++++++ 13 files changed, 1114 insertions(+), 23 deletions(-) create mode 100644 utils/false_vgui/include/VGUI.h create mode 100644 utils/false_vgui/include/VGUI_App.h create mode 100644 utils/false_vgui/include/VGUI_Bitmap.h create mode 100644 utils/false_vgui/include/VGUI_Color.h create mode 100644 utils/false_vgui/include/VGUI_Cursor.h create mode 100644 utils/false_vgui/include/VGUI_Dar.h create mode 100644 utils/false_vgui/include/VGUI_Image.h create mode 100644 utils/false_vgui/include/VGUI_KeyCode.h create mode 100644 utils/false_vgui/include/VGUI_MouseCode.h create mode 100644 utils/false_vgui/include/VGUI_Panel.h create mode 100644 utils/false_vgui/include/VGUI_Scheme.h diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 2ad46949..e52a0d95 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -28,11 +28,6 @@ set (CLDLL_LIBRARY client) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w") if (GOLDSOURCE_SUPPORT) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT -L${CMAKE_CURRENT_SOURCE_DIR}/.. -lSDL2 -Wl,--no-undefined") - if (APPLE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -l:vgui.dylib") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -l:vgui.so") - endif() endif() set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") @@ -101,7 +96,7 @@ set (CLDLL_SOURCES scoreboard.cpp MOTD.cpp) -include_directories (. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public ../utils/vgui/include) +include_directories (. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public ../utils/false_vgui/include) if(USE_VOICEMGR) #set(CLDLL_SOURCES diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index 00496ea8..1901d9d2 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -26,7 +26,6 @@ #if defined(GOLDSOURCE_SUPPORT) && (defined(_WIN32) || defined(__linux__) || defined(__APPLE__)) && (defined(__i386) || defined(_M_IX86)) #define USE_VGUI_FOR_GOLDSOURCE_SUPPORT #include "VGUI_Panel.h" -#include "VGUI_BorderLayout.h" #include "VGUI_App.h" #endif @@ -197,7 +196,7 @@ public: static TeamFortressViewport* gViewPort = NULL; -TeamFortressViewport::TeamFortressViewport(int x, int y, int wide, int tall) +TeamFortressViewport::TeamFortressViewport(int x, int y, int wide, int tall) : Panel(x, y, wide, tall) { gViewPort = this; Initialize(); @@ -205,14 +204,14 @@ TeamFortressViewport::TeamFortressViewport(int x, int y, int wide, int tall) void TeamFortressViewport::Initialize() { - vgui::App::getInstance()->setCursorOveride( vgui::App::getInstance()->getScheme()->getCursor(vgui::Scheme::scu_none) ); + //vgui::App::getInstance()->setCursorOveride( vgui::App::getInstance()->getScheme()->getCursor(vgui::Scheme::scu_none) ); } void TeamFortressViewport::paintBackground() { - int wide, tall; - getParent()->getSize( wide, tall ); - setSize( wide, tall ); +// int wide, tall; +// getParent()->getSize( wide, tall ); +// setSize( wide, tall ); gEngfuncs.VGui_ViewportPaintBackground(HUD_GetRect()); } @@ -239,17 +238,18 @@ int DLLEXPORT HUD_VidInit( void ) gHUD.VidInit(); #ifdef USE_VGUI_FOR_GOLDSOURCE_SUPPORT vgui::Panel* root=(vgui::Panel*)gEngfuncs.VGui_GetPanel(); - root->setBgColor(128,128,0,0); - root->setLayout(new vgui::BorderLayout(0)); + if (root) { + root->setBgColor(128,128,0,0); - if (gViewPort != NULL) - { - gViewPort->Initialize(); - } - else - { - gViewPort = new TeamFortressViewport(0,0,root->getWide(),root->getTall()); - gViewPort->setParent(root); + if (gViewPort != NULL) + { + gViewPort->Initialize(); + } + else + { + gViewPort = new TeamFortressViewport(0,0,root->getWide(),root->getTall()); + gViewPort->setParent(root); + } } #endif return 1; @@ -332,7 +332,10 @@ Called by engine every frame that client .dll is loaded void DLLEXPORT HUD_Frame( double time ) { -#ifndef USE_VGUI_FOR_GOLDSOURCE_SUPPORT +#ifdef USE_VGUI_FOR_GOLDSOURCE_SUPPORT + if (!gViewPort) + gEngfuncs.VGui_ViewportPaintBackground(HUD_GetRect()); +#else gEngfuncs.VGui_ViewportPaintBackground(HUD_GetRect()); #endif } diff --git a/utils/false_vgui/include/VGUI.h b/utils/false_vgui/include/VGUI.h new file mode 100644 index 00000000..0dff607a --- /dev/null +++ b/utils/false_vgui/include/VGUI.h @@ -0,0 +1,108 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_H +#define VGUI_H + +//If you are going to add stuff to the vgui core... +// +//Keep it simple. +// +//Never put code in a header. +// +//The name of the class is the name of the the file +// +//Each class gets its own .cpp file for its definition and a .h for its header. Helper +//classes can be used but only within the .cpp and not referenceable from anywhere else. +// +//Don't add unneeded files. Keep the API clean. +// +//No platform specific code in vgui\lib-src\vgui dir. Code in vgui\lib-src\vgui should +//only include from vgui\include or standard C includes. ie, if I see windows.h included +//anywhere but vgui\lib-src\win32 I will hunt you down and kill you. Don't give me any crap +//that mfc is platform inspecific. +// +//Always use <> and not "" for includes +// +//Use minimum dependencies in headers. Don't include another header if you can get away +//with forward declaring (which is usually the case) +// +//No macros in headers. They are tools of satan. This also means no use of DEFINEs, use enum +// +//Minimize global functions +// +//No global variables. +// +//Panel is getting pretty plump, try and avoid adding junk to it if you can + +//TODO: Look and Feel support +// add Panel::setPaintProxy, if _paintProxy exists, it calls _paintProxy->paint +// instead of Panel::paint. Components should implement their painting in a seperate +// plugin class. Perhaps to encourage this, Panel::paint should just go away completely +// The other option is to have Panel have the interface Paintable +// class Paintable +// { +// public: +// virtual void paint()=0; +// }; +// Then a component can implement its paint in the class itself and then call +// setPaintProxy(this). If this is the case _paintProxy->paint should always be called +// and never Panel::paint from within paintTraverse +//TODO: Figure out the 'Valve' Look and Feel and implement that instead of a the Java one +//TODO: Determine ownership policy for Borders, Layouts, etc.. +//TODO: tooltips support +//TODO: ComboKey (hot key support) +//TODO: add Background.cpp, remove paintBackground from all components +// Panel implements setBackground, Panel::paintBackground calls _background->paintBackground +// similiar to the way Border works. +//TODO: Builtin components should never overide paintBackground, only paint +//TODO: All protected members should be converted to private +//TODO: All member variables should be moved to the top of the class prototype +//TODO: All private methods should be prepended with private +//TODO: Use of word internal in method names is not consistent and confusing +//TODO: Cleanup so bullshit publics are properly named, maybe even figure out +// a naming convention for them +//TODO: Breakup InputSignal into logical pieces +//TODO: Button is in a state of disarray, it should have ButtonModel support +//TODO: get rid of all the stupid strdup laziness, convert to vgui_strdup +//TODO: actually figure out policy on String and implement it consistently +//TODO: implement createLayoutInfo for other Layouts than need it +//TODO: BorderLayout should have option for a null LayoutInfo defaulting to center +//TODO: SurfaceBase should go away, put it in Surface +//TODO: ActionSignals and other Signals should just set a flag when they fire. +// then App can come along later and fire all the signals +//TODO: Change all method naming to starting with a capital letter. + +#ifdef _WIN32 +# define VGUIAPI __declspec( dllexport ) +#else +# define VGUIAPI __attribute__ ((visibility("default"))) +#include // size_t define +#endif + +#define null 0L + +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +namespace vgui +{ + +VGUIAPI void vgui_setMalloc(void *(*malloc)(size_t size) ); +VGUIAPI void vgui_setFree(void (*free)(void* memblock)); +VGUIAPI void vgui_strcpy(char* dst,int dstLen,const char* src); +VGUIAPI char* vgui_strdup(const char* src); +VGUIAPI int vgui_printf(const char* format,...); +VGUIAPI int vgui_dprintf(const char* format,...); +VGUIAPI int vgui_dprintf2(const char* format,...); + +} + +#endif + diff --git a/utils/false_vgui/include/VGUI_App.h b/utils/false_vgui/include/VGUI_App.h new file mode 100644 index 00000000..6e70f909 --- /dev/null +++ b/utils/false_vgui/include/VGUI_App.h @@ -0,0 +1,130 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_APP_H +#define VGUI_APP_H + +#include +#include +#include +#include +#include + +namespace vgui +{ + +class Panel; +class TickSignal; +class Scheme; +class TickSignal; +class SurfaceBase; + +class VGUIAPI App +{ +public: + App() {} + App(bool externalMain) {} +public: + static App* getInstance() {return 0;} + //TODO: the public and public bullshit are all messed up, need to organize + //TODO: actually all of the access needs to be properly thought out while you are at it +public: + virtual void start() {} + virtual void stop() {} + virtual void externalTick() {} + virtual bool wasMousePressed(MouseCode code,Panel* panel) {return false;} + virtual bool wasMouseDoublePressed(MouseCode code,Panel* panel) {return false;} + virtual bool isMouseDown(MouseCode code,Panel* panel) {return false;} + virtual bool wasMouseReleased(MouseCode code,Panel* panel) {return false;} + virtual bool wasKeyPressed(KeyCode code,Panel* panel) {return false;} + virtual bool isKeyDown(KeyCode code,Panel* panel) {return false;} + virtual bool wasKeyTyped(KeyCode code,Panel* panel) {return false;} + virtual bool wasKeyReleased(KeyCode code,Panel* panel) {return false;} + virtual void addTickSignal(TickSignal* s) {} + virtual void setCursorPos(int x,int y) {} + virtual void getCursorPos(int& x,int& y) {} + virtual void setMouseCapture(Panel* panel) {} + virtual void setMouseArena(int x0,int y0,int x1,int y1,bool enabled) {} + virtual void setMouseArena(Panel* panel) {} + virtual void requestFocus(Panel* panel) {} + virtual Panel* getFocus() {return 0;} + virtual void repaintAll() {} + virtual void setScheme(Scheme* scheme) {} + virtual Scheme* getScheme() {return 0;} + virtual void enableBuildMode() {} + virtual long getTimeMillis() {return 0;} + virtual char getKeyCodeChar(KeyCode code,bool shifted) {return '\0';} + virtual void getKeyCodeText(KeyCode code,char* buf,int buflen) {} + virtual int getClipboardTextCount() {return 0;} + virtual void setClipboardText(const char* text,int textLen) {} + virtual int getClipboardText(int offset,char* buf,int bufLen) {return 0;} + virtual void reset() {} + virtual void internalSetMouseArena(int x0,int y0,int x1,int y1,bool enabled) {} + virtual bool setRegistryString(const char* key,const char* value) {return false;} + virtual bool getRegistryString(const char* key,char* value,int valueLen) {return false;} + virtual bool setRegistryInteger(const char* key,int value) {return false;} + virtual bool getRegistryInteger(const char* key,int& value) {return false;} + virtual void setCursorOveride(Cursor* cursor) {} + virtual Cursor* getCursorOveride() {return 0;} + virtual void setMinimumTickMillisInterval(int interval) {} +public: //bullshit public stuff + virtual void main(int argc,char* argv[])=0; + virtual void run() {} + virtual void internalCursorMoved(int x,int y,SurfaceBase* surfaceBase) {} //expects input in surface space + virtual void internalMousePressed(MouseCode code,SurfaceBase* surfaceBase) {} + virtual void internalMouseDoublePressed(MouseCode code,SurfaceBase* surfaceBase) {} + virtual void internalMouseReleased(MouseCode code,SurfaceBase* surfaceBase) {} + virtual void internalMouseWheeled(int delta,SurfaceBase* surfaceBase) {} + virtual void internalKeyPressed(KeyCode code,SurfaceBase* surfaceBase) {} + virtual void internalKeyTyped(KeyCode code,SurfaceBase* surfaceBase) {} + virtual void internalKeyReleased(KeyCode code,SurfaceBase* surfaceBase) {} +private: + virtual void init() {} + virtual void updateMouseFocus(int x,int y,SurfaceBase* surfaceBase) {} + virtual void setMouseFocus(Panel* newMouseFocus) {} +protected: + virtual void surfaceBaseCreated(SurfaceBase* surfaceBase) {} + virtual void surfaceBaseDeleted(SurfaceBase* surfaceBase) {} + virtual void platTick() {} + virtual void internalTick() {} +protected: + static App* _instance; +protected: + bool _running; + bool _externalMain; + Dar _surfaceBaseDar; + Panel* _keyFocus; + Panel* _oldMouseFocus; + Panel* _mouseFocus; + Panel* _mouseCapture; + Panel* _wantedKeyFocus; + bool _mousePressed[MOUSE_LAST]; + bool _mouseDoublePressed[MOUSE_LAST]; + bool _mouseDown[MOUSE_LAST]; + bool _mouseReleased[MOUSE_LAST]; + bool _keyPressed[KEY_LAST]; + bool _keyTyped[KEY_LAST]; + bool _keyDown[KEY_LAST]; + bool _keyReleased[KEY_LAST]; + Dar _tickSignalDar; + Scheme* _scheme; + bool _buildMode; + bool _wantedBuildMode; + Panel* _mouseArenaPanel; + Cursor* _cursor[Cursor::dc_last]; + Cursor* _cursorOveride; +private: + long _nextTickMillis; + long _minimumTickMillisInterval; + friend class SurfaceBase; +}; +} + +#endif + + + diff --git a/utils/false_vgui/include/VGUI_Bitmap.h b/utils/false_vgui/include/VGUI_Bitmap.h new file mode 100644 index 00000000..a2cc7a45 --- /dev/null +++ b/utils/false_vgui/include/VGUI_Bitmap.h @@ -0,0 +1,37 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_BITMAP_H +#define VGUI_BITMAP_H + +#include +#include + +namespace vgui +{ + +class Panel; + +class VGUIAPI Bitmap : public Image +{ +private: + int _id; + bool _uploaded; +public: + Bitmap() {} +protected: + virtual void setSize(int wide,int tall) {} + virtual void setRGBA(int x,int y,uchar r,uchar g,uchar b,uchar a) {} +public: + virtual void paint(Panel* panel) {} +protected: + uchar* _rgba; +}; + +} + +#endif diff --git a/utils/false_vgui/include/VGUI_Color.h b/utils/false_vgui/include/VGUI_Color.h new file mode 100644 index 00000000..f3fec5c6 --- /dev/null +++ b/utils/false_vgui/include/VGUI_Color.h @@ -0,0 +1,44 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_COLOR_H +#define VGUI_COLOR_H + +#include +#include + +//TODO: rename getColor(r,g,b,a) to getRGBA(r,g,b,a) +//TODO: rename setColor(r,g,b,a) to setRGBA(r,g,b,a) +//TODO: rename getColor(sc) to getSchemeColor(sc) +//TODO: rename setColor(sc) to setSchemeColor(sc) + +namespace vgui +{ + +class VGUIAPI Color +{ +private: + uchar _color[4]; + Scheme::SchemeColor _schemeColor; +public: + Color() {} + Color(int r,int g,int b,int a) {} + Color(Scheme::SchemeColor sc) {} +private: + virtual void init() {} +public: + virtual void setColor(int r,int g,int b,int a) {} + virtual void setColor(Scheme::SchemeColor sc) {} + virtual void getColor(int& r,int& g,int& b,int& a) {} + virtual void getColor(Scheme::SchemeColor& sc) {} + virtual int operator[](int index) {return 0;} +}; + +} + + +#endif diff --git a/utils/false_vgui/include/VGUI_Cursor.h b/utils/false_vgui/include/VGUI_Cursor.h new file mode 100644 index 00000000..8419e2dd --- /dev/null +++ b/utils/false_vgui/include/VGUI_Cursor.h @@ -0,0 +1,57 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_CURSOR_H +#define VGUI_CURSOR_H + +#include + +namespace vgui +{ + +class Bitmap; + +class VGUIAPI Cursor +{ +public: + enum DefaultCursor + { + dc_user, + dc_none, + dc_arrow, + dc_ibeam, + dc_hourglass, + dc_crosshair, + dc_up, + dc_sizenwse, + dc_sizenesw, + dc_sizewe, + dc_sizens, + dc_sizeall, + dc_no, + dc_hand, + dc_last + }; +private: + int _hotspot[2]; + Bitmap* _bitmap; + DefaultCursor _dc; +public: + Cursor(DefaultCursor dc) {} + Cursor(Bitmap* bitmap,int hotspotX,int hotspotY) {} +public: + virtual void getHotspot(int& x,int& y) {} +private: + virtual void privateInit(Bitmap* bitmap,int hotspotX,int hotspotY) {} +public: + virtual Bitmap* getBitmap() {return 0;} + virtual DefaultCursor getDefaultCursor() {return dc_none;} +}; + +} + +#endif diff --git a/utils/false_vgui/include/VGUI_Dar.h b/utils/false_vgui/include/VGUI_Dar.h new file mode 100644 index 00000000..6f8eb513 --- /dev/null +++ b/utils/false_vgui/include/VGUI_Dar.h @@ -0,0 +1,194 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_DAR_H +#define VGUI_DAR_H + +#include +#include +#include + + + +namespace vgui +{ + +//Simple lightweight dynamic array implementation +template class VGUIAPI Dar +{ +public: + Dar() + { + _count=0; + _capacity=0; + _data=null; + ensureCapacity(4); + } + Dar(int initialCapacity) + { + _count=0; + _capacity=0; + _data=null; + ensureCapacity(initialCapacity); + } +public: + void ensureCapacity(int wantedCapacity) + { + if(wantedCapacity<=_capacity){return;} + + //double capacity until it is >= wantedCapacity + //this could be done with math, but iterative is just so much more fun + int newCapacity=_capacity; + if(newCapacity==0){newCapacity=1;} + while(newCapacity_capacity)) + { + return; + } + _count=count; + } + int getCount() + { + return _count; + } + void addElement(ELEMTYPE elem) + { + ensureCapacity(_count+1); + _data[_count]=elem; + _count++; + } + bool hasElement(ELEMTYPE elem) + { + for(int i=0;i<_count;i++) + { + if(_data[i]==elem) + { + return true; + } + } + return false; + } + void putElement(ELEMTYPE elem) + { + if(hasElement(elem)) + { + return; + } + addElement(elem); + } + void insertElementAt(ELEMTYPE elem,int index) + { + if((index<0)||(index>_count)) + { + return; + } + if((index==_count)||(_count==0)) + { + addElement(elem); + } + else + { + addElement(elem); //just to make sure it is big enough + for(int i=_count-1;i>index;i--) + { + _data[i]=_data[i-1]; + } + _data[index]=elem; + } + } + void setElementAt(ELEMTYPE elem,int index) + { + if((index<0)||(index>=_count)) + { + return; + } + _data[index]=elem; + } + void removeElementAt(int index) + { + if((index<0)||(index>=_count)) + { + return; + } + + //slide everything to the right of index, left one. + for(int i=index;i<(_count-1);i++) + { + _data[i]=_data[i+1]; + } + _count--; + } + void removeElement(ELEMTYPE elem) + { + for(int i=0;i<_count;i++) + { + if(_data[i]==elem) + { + removeElementAt(i); + break; + } + } + } + void removeAll() + { + _count=0; + } + ELEMTYPE operator[](int index) + { + if((index<0)||(index>=_count)) + { + return null; + } + return _data[index]; + } +protected: + int _count; + int _capacity; + ELEMTYPE* _data; +}; + +#ifdef _WIN32 +//forward referencing all the template types used so they get exported +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar*>; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +template class VGUIAPI Dar; +#endif + +} + + +#endif \ No newline at end of file diff --git a/utils/false_vgui/include/VGUI_Image.h b/utils/false_vgui/include/VGUI_Image.h new file mode 100644 index 00000000..ff83f047 --- /dev/null +++ b/utils/false_vgui/include/VGUI_Image.h @@ -0,0 +1,62 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_IMAGE_H +#define VGUI_IMAGE_H + +#include +#include +#include + +//TODO:: needs concept of insets + +namespace vgui +{ + +class Panel; + +class VGUIAPI Image +{ +friend class Panel; +private: + int _pos[2]; + int _size[2]; + Panel* _panel; + Color _color; +public: + Image(); +public: + virtual void setPos(int x,int y) {} + virtual void getPos(int& x,int& y) {} + virtual void getSize(int& wide,int& tall) {} + virtual void setColor(Color color) {} + virtual void getColor(Color& color) {} +protected: + virtual void setSize(int wide,int tall) {} + virtual void drawSetColor(Scheme::SchemeColor sc) {} + virtual void drawSetColor(int r,int g,int b,int a) {} + virtual void drawFilledRect(int x0,int y0,int x1,int y1) {} + virtual void drawOutlinedRect(int x0,int y0,int x1,int y1) {} + virtual void drawSetTextFont(Scheme::SchemeFont sf) {} + virtual void drawSetTextFont(Font* font) {} + virtual void drawSetTextColor(Scheme::SchemeColor sc) {} + virtual void drawSetTextColor(int r,int g,int b,int a) {} + virtual void drawSetTextPos(int x,int y) {} + virtual void drawPrintText(const char* str,int strlen) {} + virtual void drawPrintText(int x,int y,const char* str,int strlen) {} + virtual void drawPrintChar(char ch) {} + virtual void drawPrintChar(int x,int y,char ch) {} + virtual void drawSetTextureRGBA(int id,const char* rgba,int wide,int tall) {} + virtual void drawSetTexture(int id) {} + virtual void drawTexturedRect(int x0,int y0,int x1,int y1) {} + virtual void paint(Panel* panel) {} +public: + virtual void doPaint(Panel* panel) {} +}; +} + +#endif diff --git a/utils/false_vgui/include/VGUI_KeyCode.h b/utils/false_vgui/include/VGUI_KeyCode.h new file mode 100644 index 00000000..b6aea363 --- /dev/null +++ b/utils/false_vgui/include/VGUI_KeyCode.h @@ -0,0 +1,126 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_KEYCODE_H +#define VGUI_KEYCODE_H + +#include + +namespace vgui +{ +enum VGUIAPI KeyCode +{ + KEY_0=0, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_A, + KEY_B, + KEY_C, + KEY_D, + KEY_E, + KEY_F, + KEY_G, + KEY_H, + KEY_I, + KEY_J, + KEY_K, + KEY_L, + KEY_M, + KEY_N, + KEY_O, + KEY_P, + KEY_Q, + KEY_R, + KEY_S, + KEY_T, + KEY_U, + KEY_V, + KEY_W, + KEY_X, + KEY_Y, + KEY_Z, + KEY_PAD_0, + KEY_PAD_1, + KEY_PAD_2, + KEY_PAD_3, + KEY_PAD_4, + KEY_PAD_5, + KEY_PAD_6, + KEY_PAD_7, + KEY_PAD_8, + KEY_PAD_9, + KEY_PAD_DIVIDE, + KEY_PAD_MULTIPLY, + KEY_PAD_MINUS, + KEY_PAD_PLUS, + KEY_PAD_ENTER, + KEY_PAD_DECIMAL, + KEY_LBRACKET, + KEY_RBRACKET, + KEY_SEMICOLON, + KEY_APOSTROPHE, + KEY_BACKQUOTE, + KEY_COMMA, + KEY_PERIOD, + KEY_SLASH, + KEY_BACKSLASH, + KEY_MINUS, + KEY_EQUAL, + KEY_ENTER, + KEY_SPACE, + KEY_BACKSPACE, + KEY_TAB, + KEY_CAPSLOCK, + KEY_NUMLOCK, + KEY_ESCAPE, + KEY_SCROLLLOCK, + KEY_INSERT, + KEY_DELETE, + KEY_HOME, + KEY_END, + KEY_PAGEUP, + KEY_PAGEDOWN, + KEY_BREAK, + KEY_LSHIFT, + KEY_RSHIFT, + KEY_LALT, + KEY_RALT, + KEY_LCONTROL, + KEY_RCONTROL, + KEY_LWIN, + KEY_RWIN, + KEY_APP, + KEY_UP, + KEY_LEFT, + KEY_DOWN, + KEY_RIGHT, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + KEY_F7, + KEY_F8, + KEY_F9, + KEY_F10, + KEY_F11, + KEY_F12, + KEY_LAST +}; +} + + +#endif + diff --git a/utils/false_vgui/include/VGUI_MouseCode.h b/utils/false_vgui/include/VGUI_MouseCode.h new file mode 100644 index 00000000..2de259db --- /dev/null +++ b/utils/false_vgui/include/VGUI_MouseCode.h @@ -0,0 +1,24 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_MOUSECODE_H +#define VGUI_MOUSECODE_H + +#include + +namespace vgui +{ +enum VGUIAPI MouseCode +{ + MOUSE_LEFT=0, + MOUSE_RIGHT, + MOUSE_MIDDLE, + MOUSE_LAST +}; +} + +#endif diff --git a/utils/false_vgui/include/VGUI_Panel.h b/utils/false_vgui/include/VGUI_Panel.h new file mode 100644 index 00000000..bec7ac25 --- /dev/null +++ b/utils/false_vgui/include/VGUI_Panel.h @@ -0,0 +1,229 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_PANEL_H +#define VGUI_PANEL_H + + +/* + +TODO: + +Maybe have the border know who they are added to. +A border can only be added to 1 thing, and will be +removed from the other. That way they can actually +be memory managed. Also do Layout's this way too. + +TODO: + outlinedRect should have a thickness arg + +*/ + + +#include +#include +#include +#include +#include +#include +#include +//#include + +namespace vgui +{ + +enum KeyCode; +enum MouseCode; +class SurfaceBase; +class FocusChangeSignal; +class InputSignal; +class Cursor; +class Layout; +class FocusNavGroup; +class Border; +class Font; +class BuildGroup; +class App; +class LayoutInfo; +class RepaintSignal; + +class VGUIAPI Panel +{ +public: + Panel() {} + Panel(int x,int y,int wide,int tall) {setPos(x, y); setSize(wide, tall);} +private: + void init(int x,int y,int wide,int tall) {} +public: + virtual void setPos(int x,int y) {_pos[0] = x; _pos[1] = y;} + virtual void getPos(int& x,int& y) {x = _pos[0]; y = _pos[1];} + virtual void setSize(int wide,int tall) {_size[0] = wide, _size[1] = tall;} + virtual void getSize(int& wide,int& tall) {wide = _size[0], tall = _size[1];} + virtual void setBounds(int x,int y,int wide,int tall) {} + virtual void getBounds(int& x,int& y,int& wide,int& tall) {} + virtual int getWide() {return _size[0];} + virtual int getTall() {return _size[1];} + virtual Panel* getParent() {return _parent;} + virtual void setVisible(bool state) {_visible = state;} + virtual bool isVisible() {return _visible;} + virtual bool isVisibleUp() {return false;} + virtual void repaint() {} + virtual void repaintAll() {} + virtual void getAbsExtents(int& x0,int& y0,int& x1,int& y1) {} + virtual void getClipRect(int& x0,int& y0,int& x1,int& y1) {} + virtual void setParent(Panel* newParent) {_parent = newParent; newParent->addChild(this);} + virtual void addChild(Panel* child) {} + virtual void insertChildAt(Panel* child,int index) {} + virtual void removeChild(Panel* child) {} + virtual bool wasMousePressed(MouseCode code) {return false;} + virtual bool wasMouseDoublePressed(MouseCode code) {return false;} + virtual bool isMouseDown(MouseCode code) {return false;} + virtual bool wasMouseReleased(MouseCode code) {return false;} + virtual bool wasKeyPressed(KeyCode code) {return false;} + virtual bool isKeyDown(KeyCode code) {return false;} + virtual bool wasKeyTyped(KeyCode code) {return false;} + virtual bool wasKeyReleased(KeyCode code) {return false;} + virtual void addInputSignal(InputSignal* s) {} + virtual void removeInputSignal(InputSignal* s) {} + virtual void addRepaintSignal(RepaintSignal* s) {} + virtual void removeRepaintSignal(RepaintSignal* s) {} + virtual bool isWithin(int x,int y) {return false;} //in screen space + virtual Panel* isWithinTraverse(int x,int y) {return 0;} + virtual void localToScreen(int& x,int& y) {} + virtual void screenToLocal(int& x,int& y) {} + virtual void setCursor(Cursor* cursor) {} + virtual void setCursor(Scheme::SchemeCursor scu) {} + virtual Cursor* getCursor() {return 0;} + virtual void setMinimumSize(int wide,int tall) {} + virtual void getMinimumSize(int& wide,int& tall) {} + virtual void requestFocus() {} + virtual bool hasFocus() {return false;} + virtual int getChildCount() {return 0;} + virtual Panel* getChild(int index) {return 0;} + virtual void setLayout(Layout* layout) {} + virtual void invalidateLayout(bool layoutNow) {} + virtual void setFocusNavGroup(FocusNavGroup* focusNavGroup) {} + virtual void requestFocusPrev() {} + virtual void requestFocusNext() {} + virtual void addFocusChangeSignal(FocusChangeSignal* s) {} + virtual bool isAutoFocusNavEnabled() {return false;} + virtual void setAutoFocusNavEnabled(bool state) {} + virtual void setBorder(Border* border) {} + virtual void setPaintBorderEnabled(bool state) {} + virtual void setPaintBackgroundEnabled(bool state) {} + virtual void setPaintEnabled(bool state) {} + virtual void getInset(int& left,int& top,int& right,int& bottom) {} + virtual void getPaintSize(int& wide,int& tall) {} + virtual void setPreferredSize(int wide,int tall) {} + virtual void getPreferredSize(int& wide,int& tall) {} + virtual SurfaceBase* getSurfaceBase() {return 0;} + virtual bool isEnabled() {return _enabled = false;} + virtual void setEnabled(bool state) {_enabled = true;} + virtual void setBuildGroup(BuildGroup* buildGroup,const char* panelPersistanceName) {} + virtual bool isBuildGroupEnabled() {return false;} + virtual void removeAllChildren() {} + virtual void repaintParent() {} + virtual Panel* createPropertyPanel() {return 0;} + virtual void getPersistanceText(char* buf,int bufLen) {} + virtual void applyPersistanceText(const char* buf) {} + virtual void setFgColor(Scheme::SchemeColor sc) {} + virtual void setBgColor(Scheme::SchemeColor sc) {} + virtual void setFgColor(int r,int g,int b,int a) {} + virtual void setBgColor(int r,int g,int b,int a) {} + virtual void getFgColor(int& r,int& g,int& b,int& a) {} + virtual void getBgColor(int& r,int& g,int& b,int& a) {} + virtual void setBgColor(Color color) {} + virtual void setFgColor(Color color) {} + virtual void getBgColor(Color& color) {} + virtual void getFgColor(Color& color) {} + virtual void setAsMouseCapture(bool state) {} + virtual void setAsMouseArena(bool state) {} + virtual App* getApp() {return 0;} + virtual void getVirtualSize(int& wide,int& tall) {} + virtual void setLayoutInfo(LayoutInfo* layoutInfo) {} + virtual LayoutInfo* getLayoutInfo() {return 0;} + virtual bool isCursorNone() {return false;} +public: //bullshit public + virtual void solveTraverse() {} + virtual void paintTraverse() {} + virtual void setSurfaceBaseTraverse(SurfaceBase* surfaceBase) {} +protected: + virtual void performLayout() {} + virtual void internalPerformLayout() {} + virtual void drawSetColor(Scheme::SchemeColor sc) {} + virtual void drawSetColor(int r,int g,int b,int a) {} + virtual void drawFilledRect(int x0,int y0,int x1,int y1) {} + virtual void drawOutlinedRect(int x0,int y0,int x1,int y1) {} + virtual void drawSetTextFont(Scheme::SchemeFont sf) {} + virtual void drawSetTextFont(Font* font) {} + virtual void drawSetTextColor(Scheme::SchemeColor sc) {} + virtual void drawSetTextColor(int r,int g,int b,int a) {} + virtual void drawSetTextPos(int x,int y) {} + virtual void drawPrintText(const char* str,int strlen) {} + virtual void drawPrintText(int x,int y,const char* str,int strlen) {} + virtual void drawPrintChar(char ch) {} + virtual void drawPrintChar(int x,int y,char ch) {} + virtual void drawSetTextureRGBA(int id,const char* rgba,int wide,int tall) {} + virtual void drawSetTexture(int id) {} + virtual void drawTexturedRect(int x0,int y0,int x1,int y1) {} + virtual void solve() {} + virtual void paintTraverse(bool repaint) {if(repaint) paintBackground();} + virtual void paintBackground() {} + virtual void paint() {} + virtual void paintBuildOverlay() {} + virtual void internalCursorMoved(int x,int y) {} + virtual void internalCursorEntered() {} + virtual void internalCursorExited() {} + virtual void internalMousePressed(MouseCode code) {} + virtual void internalMouseDoublePressed(MouseCode code) {} + virtual void internalMouseReleased(MouseCode code) {} + virtual void internalMouseWheeled(int delta) {} + virtual void internalKeyPressed(KeyCode code) {} + virtual void internalKeyTyped(KeyCode code) {} + virtual void internalKeyReleased(KeyCode code) {} + virtual void internalKeyFocusTicked() {} + virtual void internalFocusChanged(bool lost) {} + virtual void internalSetCursor() {} +protected: + int _pos[2]; + int _size[2]; + int _loc[2]; + int _minimumSize[2]; + int _preferredSize[2]; + Dar _childDar; + Panel* _parent; + SurfaceBase* _surfaceBase; + Dar _inputSignalDar; + Dar _repaintSignalDar; + int _clipRect[4]; + Cursor* _cursor; + Scheme::SchemeCursor _schemeCursor; + bool _visible; + Layout* _layout; + bool _needsLayout; + FocusNavGroup* _focusNavGroup; + Dar _focusChangeSignalDar; + bool _autoFocusNavEnabled; + Border* _border; +private: + bool _needsRepaint; + bool _enabled; + BuildGroup* _buildGroup; + Color _fgColor; + Color _bgColor; + LayoutInfo* _layoutInfo; + bool _paintBorderEnabled; + bool _paintBackgroundEnabled; + bool _paintEnabled; +friend class Panel; +friend class App; +friend class SurfaceBase; +friend class Image; +}; +} + +#endif diff --git a/utils/false_vgui/include/VGUI_Scheme.h b/utils/false_vgui/include/VGUI_Scheme.h new file mode 100644 index 00000000..e32d7976 --- /dev/null +++ b/utils/false_vgui/include/VGUI_Scheme.h @@ -0,0 +1,82 @@ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VGUI_SCHEME_H +#define VGUI_SCHEME_H + +#include + + +namespace vgui +{ + +class Font; +class Cursor; + +class VGUIAPI Scheme +{ +public: + enum SchemeColor + { + sc_user=0, + sc_black, + sc_white, + sc_primary1, + sc_primary2, + sc_primary3, + sc_secondary1, + sc_secondary2, + sc_secondary3, + sc_last + }; + enum SchemeFont + { + sf_user=0, + sf_primary1, + sf_primary2, + sf_primary3, + sf_secondary1, + sf_last + }; + enum SchemeCursor + { + scu_user=0, + scu_none, + scu_arrow, + scu_ibeam, + scu_hourglass, + scu_crosshair, + scu_up, + scu_sizenwse, + scu_sizenesw, + scu_sizewe, + scu_sizens, + scu_sizeall, + scu_no, + scu_hand, + scu_last + }; +public: + Scheme() {} +public: + virtual void setColor(SchemeColor sc,int r,int g,int b,int a) {} + virtual void getColor(SchemeColor sc,int& r,int& g,int& b,int& a) {} + virtual void setFont(SchemeFont sf,Font* font) {} + virtual Font* getFont(SchemeFont sf) {return 0;} + virtual void setCursor(SchemeCursor sc,Cursor* cursor) {} + virtual Cursor* getCursor(SchemeCursor sc) {return 0;} +protected: + int _color[sc_last][4]; + Font* _font[sf_last]; + Cursor* _cursor[scu_last]; + friend class Panel; + friend class Canvas; +}; + +} + +#endif From 33de8458d64353b2c4657a6c6648b4e1bc85cf86 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 6 Dec 2017 22:18:34 +0300 Subject: [PATCH 121/211] Some cleanup. Add false_vgui include path to makefiles --- cl_dll/Android.mk | 5 ++- cl_dll/CMakeLists.txt | 2 +- cl_dll/Makefile | 2 +- cl_dll/cdll_int.cpp | 3 ++ cl_dll/cl_dll.dsp | 4 +- utils/false_vgui/include/VGUI.h | 13 ------ utils/false_vgui/include/VGUI_Bitmap.h | 37 --------------- utils/false_vgui/include/VGUI_Image.h | 62 -------------------------- 8 files changed, 10 insertions(+), 118 deletions(-) delete mode 100644 utils/false_vgui/include/VGUI_Bitmap.h delete mode 100644 utils/false_vgui/include/VGUI_Image.h diff --git a/cl_dll/Android.mk b/cl_dll/Android.mk index 29aee174..452eb48b 100755 --- a/cl_dll/Android.mk +++ b/cl_dll/Android.mk @@ -91,7 +91,7 @@ SRCS+=./view.cpp SRCS+=./input_xash3d.cpp SRCS+=./scoreboard.cpp SRCS+=./MOTD.cpp -INCLUDES = -I../common -I. -I../game_shared -I../pm_shared -I../engine -I../dlls +INCLUDES = -I../common -I. -I../game_shared -I../pm_shared -I../engine -I../dlls -I../utils/false_vgui/include DEFINES = -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \ @@ -99,7 +99,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \ $(LOCAL_PATH)/../engine \ $(LOCAL_PATH)/../game_shared \ $(LOCAL_PATH)/../dlls \ - $(LOCAL_PATH)/../pm_shared + $(LOCAL_PATH)/../pm_shared \ + $(LOCAL_PATH)/../utils/false_vgui/include LOCAL_CFLAGS += $(DEFINES) $(INCLUDES) ifeq ($(GOLDSOURCE_SUPPORT),1) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index e52a0d95..e5a3aa0a 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -27,7 +27,7 @@ set (CLDLL_LIBRARY client) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w") if (GOLDSOURCE_SUPPORT) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT -L${CMAKE_CURRENT_SOURCE_DIR}/.. -lSDL2 -Wl,--no-undefined") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT -lSDL2") endif() set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") diff --git a/cl_dll/Makefile b/cl_dll/Makefile index 16427f8f..f624473e 100644 --- a/cl_dll/Makefile +++ b/cl_dll/Makefile @@ -67,7 +67,7 @@ SRCS+=./view.cpp SRCS+=./input_xash3d.cpp SRCS+=./scoreboard.cpp SRCS+=./MOTD.cpp -INCLUDES = -I../common -I. -I../game_shared -I../pm_shared -I../engine -I../dlls +INCLUDES = -I../common -I. -I../game_shared -I../pm_shared -I../engine -I../dlls -I../utils/false_vgui/include DEFINES = -Wno-write-strings -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL CFLAGS = -m32 OBJS = $(SRCS:.cpp=.o) $(SRCS_C:.c=.o) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index 1901d9d2..7427ef80 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -239,6 +239,7 @@ int DLLEXPORT HUD_VidInit( void ) #ifdef USE_VGUI_FOR_GOLDSOURCE_SUPPORT vgui::Panel* root=(vgui::Panel*)gEngfuncs.VGui_GetPanel(); if (root) { + gEngfuncs.Con_Printf( "Root VGUI panel exists\n" ); root->setBgColor(128,128,0,0); if (gViewPort != NULL) @@ -250,6 +251,8 @@ int DLLEXPORT HUD_VidInit( void ) gViewPort = new TeamFortressViewport(0,0,root->getWide(),root->getTall()); gViewPort->setParent(root); } + } else { + gEngfuncs.Con_Printf( "Root VGUI panel does not exist\n" ); } #endif return 1; diff --git a/cl_dll/cl_dll.dsp b/cl_dll/cl_dll.dsp index e8ae7d15..17beb9ae 100644 --- a/cl_dll/cl_dll.dsp +++ b/cl_dll/cl_dll.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 1 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\utils\vgui\include" /I "..\engine" /I "..\common" /I "..\pm_shared" /I "..\dlls" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\utils\false_vgui\include" /I "..\engine" /I "..\common" /I "..\pm_shared" /I "..\dlls" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /YX /FD /c # SUBTRACT CPP /Z # ADD BASE MTL /nologo /D "NDEBUG" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 @@ -80,7 +80,7 @@ SOURCE="$(InputPath)" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /G5 /MTd /W3 /Gm /GR /GX /ZI /Od /I "..\dlls" /I "..\common" /I "..\pm_shared" /I "..\engine" /I "..\utils\vgui\include" /I "..\game_shared" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /FR /YX /FD /c +# ADD CPP /nologo /G5 /MTd /W3 /Gm /GR /GX /ZI /Od /I "..\dlls" /I "..\common" /I "..\pm_shared" /I "..\engine" /I "..\utils\false_vgui\include" /I "..\game_shared" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "CLIENT_DLL" /D "CLIENT_WEAPONS" /FR /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" diff --git a/utils/false_vgui/include/VGUI.h b/utils/false_vgui/include/VGUI.h index 0dff607a..c33e0589 100644 --- a/utils/false_vgui/include/VGUI.h +++ b/utils/false_vgui/include/VGUI.h @@ -91,18 +91,5 @@ typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; -namespace vgui -{ - -VGUIAPI void vgui_setMalloc(void *(*malloc)(size_t size) ); -VGUIAPI void vgui_setFree(void (*free)(void* memblock)); -VGUIAPI void vgui_strcpy(char* dst,int dstLen,const char* src); -VGUIAPI char* vgui_strdup(const char* src); -VGUIAPI int vgui_printf(const char* format,...); -VGUIAPI int vgui_dprintf(const char* format,...); -VGUIAPI int vgui_dprintf2(const char* format,...); - -} - #endif diff --git a/utils/false_vgui/include/VGUI_Bitmap.h b/utils/false_vgui/include/VGUI_Bitmap.h deleted file mode 100644 index a2cc7a45..00000000 --- a/utils/false_vgui/include/VGUI_Bitmap.h +++ /dev/null @@ -1,37 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef VGUI_BITMAP_H -#define VGUI_BITMAP_H - -#include -#include - -namespace vgui -{ - -class Panel; - -class VGUIAPI Bitmap : public Image -{ -private: - int _id; - bool _uploaded; -public: - Bitmap() {} -protected: - virtual void setSize(int wide,int tall) {} - virtual void setRGBA(int x,int y,uchar r,uchar g,uchar b,uchar a) {} -public: - virtual void paint(Panel* panel) {} -protected: - uchar* _rgba; -}; - -} - -#endif diff --git a/utils/false_vgui/include/VGUI_Image.h b/utils/false_vgui/include/VGUI_Image.h deleted file mode 100644 index ff83f047..00000000 --- a/utils/false_vgui/include/VGUI_Image.h +++ /dev/null @@ -1,62 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef VGUI_IMAGE_H -#define VGUI_IMAGE_H - -#include -#include -#include - -//TODO:: needs concept of insets - -namespace vgui -{ - -class Panel; - -class VGUIAPI Image -{ -friend class Panel; -private: - int _pos[2]; - int _size[2]; - Panel* _panel; - Color _color; -public: - Image(); -public: - virtual void setPos(int x,int y) {} - virtual void getPos(int& x,int& y) {} - virtual void getSize(int& wide,int& tall) {} - virtual void setColor(Color color) {} - virtual void getColor(Color& color) {} -protected: - virtual void setSize(int wide,int tall) {} - virtual void drawSetColor(Scheme::SchemeColor sc) {} - virtual void drawSetColor(int r,int g,int b,int a) {} - virtual void drawFilledRect(int x0,int y0,int x1,int y1) {} - virtual void drawOutlinedRect(int x0,int y0,int x1,int y1) {} - virtual void drawSetTextFont(Scheme::SchemeFont sf) {} - virtual void drawSetTextFont(Font* font) {} - virtual void drawSetTextColor(Scheme::SchemeColor sc) {} - virtual void drawSetTextColor(int r,int g,int b,int a) {} - virtual void drawSetTextPos(int x,int y) {} - virtual void drawPrintText(const char* str,int strlen) {} - virtual void drawPrintText(int x,int y,const char* str,int strlen) {} - virtual void drawPrintChar(char ch) {} - virtual void drawPrintChar(int x,int y,char ch) {} - virtual void drawSetTextureRGBA(int id,const char* rgba,int wide,int tall) {} - virtual void drawSetTexture(int id) {} - virtual void drawTexturedRect(int x0,int y0,int x1,int y1) {} - virtual void paint(Panel* panel) {} -public: - virtual void doPaint(Panel* panel) {} -}; -} - -#endif From ca590f24208f7cf37889f833286822e33f4a1b5f Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 7 Dec 2017 00:31:27 +0300 Subject: [PATCH 122/211] Use old API to draw scoreboard and motd lines in goldsource --- cl_dll/cdll_int.cpp | 5 +++++ cl_dll/cl_util.h | 6 +++++- cl_dll/hud_redraw.cpp | 48 ++++++++++++++++++++++++------------------ cl_dll/input_mouse.cpp | 3 ++- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index d71659e9..80b45e31 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -305,3 +305,8 @@ void DLLEXPORT HUD_MobilityInterface( mobile_engfuncs_t *gpMobileEngfuncs ) return; gMobileEngfuncs = gpMobileEngfuncs; } + +bool isXashFWGS() +{ + return gMobileEngfuncs != NULL; +} diff --git a/cl_dll/cl_util.h b/cl_dll/cl_util.h index 1996543d..23f12230 100644 --- a/cl_dll/cl_util.h +++ b/cl_dll/cl_util.h @@ -15,7 +15,8 @@ // // cl_util.h // - +#ifndef CL_UTIL_H +#define CL_UTIL_H #include "exportdef.h" #include "cvardef.h" @@ -179,3 +180,6 @@ inline void UnpackRGB( int &r, int &g, int &b, unsigned long ulRGB )\ } HSPRITE LoadSprite( const char *pszName ); + +bool isXashFWGS(); +#endif diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index 829fd4b2..06b25a33 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -235,29 +235,35 @@ int CHud::DrawHudString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int DrawUtfString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int g, int b ) { - // xash3d: reset unicode state - gEngfuncs.pfnVGUI2DrawCharacterAdditive( 0, 0, 0, 0, 0, 0, 0 ); - - // draw the string until we hit the null character or a newline character - for( ; *szIt != 0 && *szIt != '\n'; szIt++ ) + if (isXashFWGS()) { - int w = gHUD.m_scrinfo.charWidths['M']; - if( xpos + w > iMaxX ) - return xpos; - if( ( *szIt == '^' ) && ( *( szIt + 1 ) >= '0') && ( *( szIt + 1 ) <= '7') ) - { - szIt++; - r = colors[*szIt - '0'][0]; - g = colors[*szIt - '0'][1]; - b = colors[*szIt - '0'][2]; - if( !*(++szIt) ) - return xpos; - } - int c = (unsigned int)(unsigned char)*szIt; - xpos += gEngfuncs.pfnVGUI2DrawCharacterAdditive( xpos, ypos, c, r, g, b, 0 ); - } + // xash3d: reset unicode state + gEngfuncs.pfnVGUI2DrawCharacterAdditive( 0, 0, 0, 0, 0, 0, 0 ); - return xpos; + // draw the string until we hit the null character or a newline character + for( ; *szIt != 0 && *szIt != '\n'; szIt++ ) + { + int w = gHUD.m_scrinfo.charWidths['M']; + if( xpos + w > iMaxX ) + return xpos; + if( ( *szIt == '^' ) && ( *( szIt + 1 ) >= '0') && ( *( szIt + 1 ) <= '7') ) + { + szIt++; + r = colors[*szIt - '0'][0]; + g = colors[*szIt - '0'][1]; + b = colors[*szIt - '0'][2]; + if( !*(++szIt) ) + return xpos; + } + int c = (unsigned int)(unsigned char)*szIt; + xpos += gEngfuncs.pfnVGUI2DrawCharacterAdditive( xpos, ypos, c, r, g, b, 0 ); + } + return xpos; + } + else + { + return gHUD.DrawHudString(xpos, ypos, iMaxX, szIt, r, g, b); + } } int CHud::DrawHudStringLen( const char *szIt ) diff --git a/cl_dll/input_mouse.cpp b/cl_dll/input_mouse.cpp index 724824cd..8d57091b 100644 --- a/cl_dll/input_mouse.cpp +++ b/cl_dll/input_mouse.cpp @@ -1,6 +1,7 @@ #include "input_mouse.h" #include "exportdef.h" #include "hud.h" +#include "cl_util.h" // shared between backends Vector dead_viewangles(0, 0, 0); @@ -68,7 +69,7 @@ void IN_Shutdown( void ) void IN_Init( void ) { #ifdef SUPPORT_GOLDSOURCE_INPUT - if (gMobileEngfuncs) { + if (isXashFWGS()) { gEngfuncs.Con_Printf( "FWGS Xash3D input is in use\n" ); currentInput = &fwgsInput; } else { From 1759e8c956e1d4cbd42e9a6d17c1d4208b5b8f1a Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 7 Dec 2017 01:25:59 +0300 Subject: [PATCH 123/211] Dynamic sdl2 loading from client --- cl_dll/CMakeLists.txt | 5 ++- cl_dll/input_goldsource.cpp | 73 ++++++++++++++++++++++++++++--------- cl_dll/input_mouse.h | 1 + 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index e5a3aa0a..e3ac075a 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -27,7 +27,10 @@ set (CLDLL_LIBRARY client) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w") if (GOLDSOURCE_SUPPORT) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT -lSDL2") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT") + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ldl") + endif() endif() set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index 5c2b0381..7c0e6183 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -28,8 +28,18 @@ #endif #ifdef USE_SDL2 +#include #include #include +int (*pfnSDL_SetRelativeMouseMode)(SDL_bool); +Uint32 (*pfnSDL_GetRelativeMouseState)(int* x, int* y); +int (*pfnSDL_NumJoysticks)(void); +SDL_bool (*pfnSDL_IsGameController)(int); +SDL_GameController* (*pfnSDL_GameControllerOpen)(int); +Sint16 (*pfnSDL_GameControllerGetAxis)(SDL_GameController*, SDL_GameControllerAxis); +Uint8 (*pfnSDL_GameControllerGetButton)(SDL_GameController*, SDL_GameControllerButton); +void (*pfnSDL_JoystickUpdate)(void); +const char* (*pfnSDL_GameControllerName)(SDL_GameController*); #endif #ifdef _WIN32 @@ -289,12 +299,12 @@ void IN_SetMouseMode(bool enable) if(m_bRawInput) { #ifdef USE_SDL2 - SDL_SetRelativeMouseMode(SDL_TRUE); + pfnSDL_SetRelativeMouseMode(SDL_TRUE); #endif isMouseRelative = true; } #else - SDL_SetRelativeMouseMode(SDL_TRUE); + pfnSDL_SetRelativeMouseMode(SDL_TRUE); #endif currentMouseMode = true; @@ -305,7 +315,7 @@ void IN_SetMouseMode(bool enable) if(isMouseRelative) { #ifdef USE_SDL2 - SDL_SetRelativeMouseMode(SDL_FALSE); + pfnSDL_SetRelativeMouseMode(SDL_FALSE); #endif isMouseRelative = false; } @@ -313,7 +323,7 @@ void IN_SetMouseMode(bool enable) if (restore_spi) SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); #else - SDL_SetRelativeMouseMode(SDL_FALSE); + pfnSDL_SetRelativeMouseMode(SDL_FALSE); #endif currentMouseMode = false; @@ -464,6 +474,11 @@ void GoldSourceInput::IN_Shutdown (void) s_hMouseThreadActiveLock = (HANDLE)0; } #endif + +#ifdef USE_SDL2 + dlclose(sdl2Lib); + sdl2Lib = NULL; +#endif } /* @@ -623,7 +638,7 @@ void GoldSourceInput::IN_GetMouseDelta( int *pOutX, int *pOutY) #endif { #ifdef USE_SDL2 - SDL_GetRelativeMouseState( &deltaX, &deltaY ); + pfnSDL_GetRelativeMouseState( &deltaX, &deltaY ); current_pos.x = deltaX; current_pos.y = deltaY; #else @@ -679,14 +694,14 @@ void GoldSourceInput::IN_GetMouseDelta( int *pOutX, int *pOutY) if(m_bRawInput && !isMouseRelative) { #ifdef USE_SDL2 - SDL_SetRelativeMouseMode(SDL_TRUE); + pfnSDL_SetRelativeMouseMode(SDL_TRUE); #endif isMouseRelative = true; } else if(!m_bRawInput && isMouseRelative) { #ifdef USE_SDL2 - SDL_SetRelativeMouseMode(SDL_FALSE); + pfnSDL_SetRelativeMouseMode(SDL_FALSE); #endif isMouseRelative = false; } @@ -815,7 +830,7 @@ void GoldSourceInput::IN_Accumulate (void) { #ifdef USE_SDL2 int deltaX, deltaY; - SDL_GetRelativeMouseState( &deltaX, &deltaY ); + pfnSDL_GetRelativeMouseState( &deltaX, &deltaY ); mx_accum += deltaX; my_accum += deltaY; #else @@ -869,14 +884,14 @@ void IN_StartupJoystick (void) // assume no joystick joy_avail = 0; #ifdef USE_SDL2 - int nJoysticks = SDL_NumJoysticks(); + int nJoysticks = pfnSDL_NumJoysticks(); if ( nJoysticks > 0 ) { for ( int i = 0; i < nJoysticks; i++ ) { - if ( SDL_IsGameController( i ) ) + if ( pfnSDL_IsGameController( i ) ) { - s_pJoystick = SDL_GameControllerOpen( i ); + s_pJoystick = pfnSDL_GameControllerOpen( i ); if ( s_pJoystick ) { //save the joystick's number of buttons and POV status @@ -888,7 +903,7 @@ void IN_StartupJoystick (void) // mark the joystick as available and advanced initialization not completed // this is needed as cvars are not available during initialization - gEngfuncs.Con_Printf ("joystick found\n\n", SDL_GameControllerName(s_pJoystick)); + gEngfuncs.Con_Printf ("joystick found\n\n", pfnSDL_GameControllerName(s_pJoystick)); joy_avail = 1; joy_advancedinit = 0; break; @@ -912,13 +927,13 @@ int RawValuePointer (int axis) { default: case JOY_AXIS_X: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX ); + return pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX ); case JOY_AXIS_Y: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY ); + return pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY ); case JOY_AXIS_Z: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX ); + return pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX ); case JOY_AXIS_R: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY ); + return pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY ); } #else @@ -1011,7 +1026,7 @@ void GoldSourceInput::IN_Commands (void) #ifdef USE_SDL2 for ( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) { - if ( SDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) ) + if ( pfnSDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) ) { buttonstate |= 1< Date: Thu, 7 Dec 2017 04:43:25 +0300 Subject: [PATCH 124/211] Provide safe wrappers around sdl function pointers. Use dylib extension on macOS --- cl_dll/input_goldsource.cpp | 137 ++++++++++++++++++++++++++++-------- 1 file changed, 108 insertions(+), 29 deletions(-) diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index 7c0e6183..e367a37e 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -40,6 +40,63 @@ Sint16 (*pfnSDL_GameControllerGetAxis)(SDL_GameController*, SDL_GameControllerAx Uint8 (*pfnSDL_GameControllerGetButton)(SDL_GameController*, SDL_GameControllerButton); void (*pfnSDL_JoystickUpdate)(void); const char* (*pfnSDL_GameControllerName)(SDL_GameController*); + +int safe_pfnSDL_SetRelativeMouseMode(SDL_bool mode) +{ + if (pfnSDL_SetRelativeMouseMode) + return pfnSDL_SetRelativeMouseMode(mode); + return -1; +} +Uint32 safe_pfnSDL_GetRelativeMouseState(int* x, int* y) +{ + if (pfnSDL_GetRelativeMouseState) + return pfnSDL_GetRelativeMouseState(x, y); + return 0; +} +int safe_pfnSDL_NumJoysticks() +{ + if (pfnSDL_NumJoysticks) + return pfnSDL_NumJoysticks(); + return -1; +} +SDL_bool safe_pfnSDL_IsGameController(int joystick_index) +{ + if (pfnSDL_IsGameController) + return pfnSDL_IsGameController(joystick_index); + return SDL_FALSE; +} +SDL_GameController* safe_pfnSDL_GameControllerOpen(int joystick_index) +{ + if (pfnSDL_GameControllerOpen) + return pfnSDL_GameControllerOpen(joystick_index); + return NULL; +} +Sint16 safe_pfnSDL_GameControllerGetAxis(SDL_GameController* gamecontroller, SDL_GameControllerAxis axis) +{ + if (pfnSDL_GameControllerGetAxis) + return pfnSDL_GameControllerGetAxis(gamecontroller, axis); + return 0; +} +Uint8 safe_pfnSDL_GameControllerGetButton(SDL_GameController* gamecontroller, SDL_GameControllerButton button) +{ + if (pfnSDL_GameControllerGetButton) + return pfnSDL_GameControllerGetButton(gamecontroller, button); + return 0; +} +void safe_pfnSDL_JoystickUpdate() +{ + if (pfnSDL_JoystickUpdate) + pfnSDL_JoystickUpdate(); +} +const char* safe_pfnSDL_GameControllerName(SDL_GameController* gamecontroller) +{ + if (pfnSDL_GameControllerName) + return pfnSDL_GameControllerName(gamecontroller); + return NULL; +} +static void** const sdlFunctionPointers[] = {(void**)&pfnSDL_SetRelativeMouseMode, (void**)&pfnSDL_GetRelativeMouseState, (void**)&pfnSDL_NumJoysticks, + (void**)&pfnSDL_IsGameController, (void**)&pfnSDL_GameControllerOpen, (void**)&pfnSDL_GameControllerGetAxis, + (void**)&pfnSDL_GameControllerGetButton, (void**)&pfnSDL_JoystickUpdate, (void**)&pfnSDL_GameControllerName}; #endif #ifdef _WIN32 @@ -299,12 +356,12 @@ void IN_SetMouseMode(bool enable) if(m_bRawInput) { #ifdef USE_SDL2 - pfnSDL_SetRelativeMouseMode(SDL_TRUE); + safe_pfnSDL_SetRelativeMouseMode(SDL_TRUE); #endif isMouseRelative = true; } #else - pfnSDL_SetRelativeMouseMode(SDL_TRUE); + safe_pfnSDL_SetRelativeMouseMode(SDL_TRUE); #endif currentMouseMode = true; @@ -315,7 +372,7 @@ void IN_SetMouseMode(bool enable) if(isMouseRelative) { #ifdef USE_SDL2 - pfnSDL_SetRelativeMouseMode(SDL_FALSE); + safe_pfnSDL_SetRelativeMouseMode(SDL_FALSE); #endif isMouseRelative = false; } @@ -323,7 +380,7 @@ void IN_SetMouseMode(bool enable) if (restore_spi) SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); #else - pfnSDL_SetRelativeMouseMode(SDL_FALSE); + safe_pfnSDL_SetRelativeMouseMode(SDL_FALSE); #endif currentMouseMode = false; @@ -476,6 +533,9 @@ void GoldSourceInput::IN_Shutdown (void) #endif #ifdef USE_SDL2 + for (int j=0; j 0 ) { for ( int i = 0; i < nJoysticks; i++ ) { - if ( pfnSDL_IsGameController( i ) ) + if ( safe_pfnSDL_IsGameController( i ) ) { - s_pJoystick = pfnSDL_GameControllerOpen( i ); + s_pJoystick = safe_pfnSDL_GameControllerOpen( i ); if ( s_pJoystick ) { //save the joystick's number of buttons and POV status @@ -903,7 +963,7 @@ void IN_StartupJoystick (void) // mark the joystick as available and advanced initialization not completed // this is needed as cvars are not available during initialization - gEngfuncs.Con_Printf ("joystick found\n\n", pfnSDL_GameControllerName(s_pJoystick)); + gEngfuncs.Con_Printf ("joystick found\n\n", safe_pfnSDL_GameControllerName(s_pJoystick)); joy_avail = 1; joy_advancedinit = 0; break; @@ -927,13 +987,13 @@ int RawValuePointer (int axis) { default: case JOY_AXIS_X: - return pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX ); + return safe_pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX ); case JOY_AXIS_Y: - return pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY ); + return safe_pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY ); case JOY_AXIS_Z: - return pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX ); + return safe_pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX ); case JOY_AXIS_R: - return pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY ); + return safe_pfnSDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY ); } #else @@ -1026,7 +1086,7 @@ void GoldSourceInput::IN_Commands (void) #ifdef USE_SDL2 for ( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) { - if ( pfnSDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) ) + if ( safe_pfnSDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) ) { buttonstate |= 1< Date: Thu, 7 Dec 2017 21:25:26 +0300 Subject: [PATCH 125/211] sdl loading refactoring --- cl_dll/input_goldsource.cpp | 58 ++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index e367a37e..38dac71d 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -28,6 +28,7 @@ #endif #ifdef USE_SDL2 +#define ARRAYSIZE(p) ( sizeof(p) /sizeof(p[0]) ) #include #include #include @@ -94,9 +95,23 @@ const char* safe_pfnSDL_GameControllerName(SDL_GameController* gamecontroller) return pfnSDL_GameControllerName(gamecontroller); return NULL; } -static void** const sdlFunctionPointers[] = {(void**)&pfnSDL_SetRelativeMouseMode, (void**)&pfnSDL_GetRelativeMouseState, (void**)&pfnSDL_NumJoysticks, - (void**)&pfnSDL_IsGameController, (void**)&pfnSDL_GameControllerOpen, (void**)&pfnSDL_GameControllerGetAxis, - (void**)&pfnSDL_GameControllerGetButton, (void**)&pfnSDL_JoystickUpdate, (void**)&pfnSDL_GameControllerName}; + +struct SDLFunction +{ + void** ppfnFunc; + const char* name; +}; +static SDLFunction sdlFunctions[] = { + {(void**)&pfnSDL_SetRelativeMouseMode, "SDL_SetRelativeMouseMode"}, + {(void**)&pfnSDL_GetRelativeMouseState, "SDL_GetRelativeMouseState"}, + {(void**)&pfnSDL_NumJoysticks, "SDL_NumJoysticks"}, + {(void**)&pfnSDL_IsGameController, "SDL_IsGameController"}, + {(void**)&pfnSDL_GameControllerOpen, "SDL_GameControllerOpen"}, + {(void**)&pfnSDL_GameControllerGetAxis, "SDL_GameControllerGetAxis"}, + {(void**)&pfnSDL_GameControllerGetButton, "SDL_GameControllerGetButton"}, + {(void**)&pfnSDL_JoystickUpdate, "SDL_JoystickUpdate"}, + {(void**)&pfnSDL_GameControllerName, "SDL_GameControllerName"} +}; #endif #ifdef _WIN32 @@ -533,8 +548,8 @@ void GoldSourceInput::IN_Shutdown (void) #endif #ifdef USE_SDL2 - for (int j=0; j Date: Sat, 9 Dec 2017 00:16:29 +0300 Subject: [PATCH 126/211] Update README.md, update makefiles, add .bat scripts for msvc --- README.md | 92 +++++++++++++++++++++++++++++----- cl_dll/Android.mk | 4 +- cl_dll/Makefile | 1 - cl_dll/compile.bat | 84 +++++++++++++++++++++++++++++++ dlls/Makefile | 4 +- dlls/compile.bat | 121 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 291 insertions(+), 15 deletions(-) create mode 100644 cl_dll/compile.bat create mode 100644 dlls/compile.bat diff --git a/README.md b/README.md index bb1cc675..21db93fb 100644 --- a/README.md +++ b/README.md @@ -6,22 +6,41 @@ Half-Life SDK for Xash3D & GoldSource with some fixes. ### CMake as most universal way -``` -mkdir build && cd build -cmake ../ -``` + mkdir build && cd build + cmake ../ + make You may enable or disable some build options by -Dkey=value. All available build options are defined in CMakeLists.txt at root directory. +See below if you want to build the GoldSource compatible libraries. See below, if CMake is not suitable for you: ### Windows +#### Using msvc + +We use compilers provided with Microsoft Visual Studio 6. There're `compile.bat` scripts in both `cl_dll` and `dlls` directories. +Before running any of those files you must define `MSVCDir` variable which is the path to your msvc installation. + + set MSVCDir=C:\Program Files\Microsoft Visual Studio + compile.bat + +These scripts also can be ran via wine: + + MSVCDir="z:\home\$USER\.wine\drive_c\Program Files\Microsoft Visual Studio" wine cmd /c compile.bat + +The libraries built this way are always GoldSource compatible. + +There're dsp projects for MVS 6 in `cl_dll` and `dlls` directories, but we don't keep them up-to-date. You're free to adapt them for yourself and try to import into the newer MVS versions. + +#### Using mingw + TODO ### Linux -TODO + (cd dlls && make) + (cd cl_dll && make) ### OS X @@ -29,14 +48,65 @@ TODO ### FreeBSD -``` - cd dlls - gmake CXX=clang++ CC=clang - cd ../cl_dll - gmake CXX=clang++ CC=clang -``` + (cd dlls && gmake CXX=clang++ CC=clang) + (cd cl_dll && gmake CXX=clang++ CC=clang) ### Android Just typical `ndk-build`. +TODO: describe what it is. +### Building GoldSource-compatible libraries + +To enable building the goldsource compatible client library add GOLDSOURCE_SUPPORT flag when calling cmake: + + cmake .. -DGOLDSOURCE_SUPPORT=ON + +or when using make without cmake: + + make GOLDSOURCE_SUPPORT=1 + +Unlike original client by Valve the resulting client library will not depend on vgui or SDL2 just like the one that's used in FWGS Xash3d. + +Note for **Linux**: GoldSource requires libraries (both client and server) to be compiled with libstdc++ bundled with g++ of major version 4 (versions from 4.6 to 4.9 should work). +If your Linux distribution does not provide compatible g++ version you have several options. + +#### Method 1: Statically build with c++ library + +This one is the most simple but has a drawback. + + cmake ../ -DGOLDSOURCE_SUPPORT=ON -DCMAKE_C_FLAGS="-static-libstdc++ -static-libgcc" + +The drawback is that the compiled libraries will be larger in size. + +#### Method 2: Create and use chroot with older distro that includes g++ 4. + +Use the most suitable way for you to create an old distro 32-bit chroot. E.g. on Debian (and similar) you can use debootstrap. + + sudo debootstrap --arch=i386 jessie /var/chroot/jessie-debian-i386 # On Ubuntu type trusty instead of jessie + sudo chroot /var/chroot/jessie-debian-i386 + +Inside chroot install cmake, make, g++ and libsdl2-dev. Then exit the chroot. + +On the host system install schroot. Then create and adapt the following config in /etc/schroot/chroot.d/jessie.conf (you can choose a different name): + +``` +[jessie] +type=directory +description=Debian jessie i386 +directory=/var/chroot/debian-jessie-i386/ +users=yourusername +groups=yourusername +root-groups=root +preserve-environment=true +personality=linux32 +``` + +Insert your actual user name in place of `yourusername`. Then prepend any make or cmake call with `schroot -c jessie --`: + + schroot -c jessie -- cmake ../ -DGOLDSOURCE_SUPPORT=ON + schroot -c jessie -- make + +#### Method 3: Install the needed g++ version yourself + +TODO: describe steps. diff --git a/cl_dll/Android.mk b/cl_dll/Android.mk index 452eb48b..68917633 100755 --- a/cl_dll/Android.mk +++ b/cl_dll/Android.mk @@ -105,7 +105,9 @@ LOCAL_CFLAGS += $(DEFINES) $(INCLUDES) ifeq ($(GOLDSOURCE_SUPPORT),1) DEFINES += -DGOLDSOURCE_SUPPORT - LOCAL_LDLIBS += -lSDL2 + ifeq ($(shell uname -s),Linux) + LOCAL_LDLIBS += -ldl + endif endif LOCAL_SRC_FILES := $(SRCS) $(SRCS_C) diff --git a/cl_dll/Makefile b/cl_dll/Makefile index f624473e..0ff4dadf 100644 --- a/cl_dll/Makefile +++ b/cl_dll/Makefile @@ -75,7 +75,6 @@ OBJS = $(SRCS:.cpp=.o) $(SRCS_C:.c=.o) LIBS=-lm ifeq ($(GOLDSOURCE_SUPPORT),1) DEFINES += -DGOLDSOURCE_SUPPORT - LIBS += -lSDL2 endif ifeq ($(shell uname -s),Linux) diff --git a/cl_dll/compile.bat b/cl_dll/compile.bat new file mode 100644 index 00000000..9270d4bc --- /dev/null +++ b/cl_dll/compile.bat @@ -0,0 +1,84 @@ +@echo off +echo Setting environment for minimal Visual C++ 6 +set INCLUDE=%MSVCDir%\VC98\Include +set LIB=%MSVCDir%\VC98\Lib +set PATH=%MSVCDir%\VC98\Bin;%MSVCDir%\Common\MSDev98\Bin\;%PATH% + +echo -- Compiler is MSVC6 + +set XASH3DSRC=..\..\Xash3D_original +set INCLUDES=-I../common -I../engine -I../pm_shared -I../game_shared -I../public -I../external -I../dlls -I../utils/false_vgui/include +set SOURCES=../dlls/crossbow.cpp^ + ../dlls/crowbar.cpp^ + ../dlls/egon.cpp^ + ../dlls/gauss.cpp^ + ../dlls/handgrenade.cpp^ + ../dlls/hornetgun.cpp^ + ../dlls/mp5.cpp^ + ../dlls/python.cpp^ + ../dlls/rpg.cpp^ + ../dlls/satchel.cpp^ + ../dlls/shotgun.cpp^ + ../dlls/squeakgrenade.cpp^ + ../dlls/tripmine.cpp^ + ../dlls/glock.cpp^ + ev_hldm.cpp^ + hl/hl_baseentity.cpp^ + hl/hl_events.cpp^ + hl/hl_objects.cpp^ + hl/hl_weapons.cpp^ + ammo.cpp^ + ammo_secondary.cpp^ + ammohistory.cpp^ + battery.cpp^ + cdll_int.cpp^ + com_weapons.cpp^ + death.cpp^ + demo.cpp^ + entity.cpp^ + ev_common.cpp^ + events.cpp^ + flashlight.cpp^ + GameStudioModelRenderer.cpp^ + geiger.cpp^ + health.cpp^ + hud.cpp^ + hud_msg.cpp^ + hud_redraw.cpp^ + hud_spectator.cpp^ + hud_update.cpp^ + in_camera.cpp^ + input.cpp^ + input_goldsource.cpp^ + input_mouse.cpp^ + input_xash3d.cpp^ + menu.cpp^ + message.cpp^ + overview.cpp^ + parsemsg.cpp^ + ../pm_shared/pm_debug.c^ + ../pm_shared/pm_math.c^ + ../pm_shared/pm_shared.c^ + saytext.cpp^ + status_icons.cpp^ + statusbar.cpp^ + studio_util.cpp^ + StudioModelRenderer.cpp^ + text_message.cpp^ + train.cpp^ + tri.cpp^ + util.cpp^ + view.cpp^ + scoreboard.cpp^ + MOTD.cpp +set DEFINES=/DCLIENT_DLL /DCLIENT_WEAPONS /Dsnprintf=_snprintf /DNO_VOICEGAMEMGR /DGOLDSOURCE_SUPPORT +set LIBS=user32.lib Winmm.lib +set OUTNAME=client.dll +set DEBUG=/debug + +cl %DEFINES% %LIBS% %SOURCES% %INCLUDES% -o %OUTNAME% /link /dll /out:%OUTNAME% %DEBUG% + +echo -- Compile done. Cleaning... + +del *.obj *.exp *.lib *.ilk +echo -- Done. diff --git a/dlls/Makefile b/dlls/Makefile index 60aad1b3..3599b9c7 100644 --- a/dlls/Makefile +++ b/dlls/Makefile @@ -129,13 +129,13 @@ OBJ = \ $(DLL_OBJDIR)/multiplay_gamerules.o \ $(DLL_OBJDIR)/nihilanth.o \ $(DLL_OBJDIR)/nodes.o \ - $(DLL_OBJDIR)/observer.cpp \^M + $(DLL_OBJDIR)/observer.o \ $(DLL_OBJDIR)/osprey.o \ $(DLL_OBJDIR)/pathcorner.o \ $(DLL_OBJDIR)/plane.o \ $(DLL_OBJDIR)/plats.o \ $(DLL_OBJDIR)/player.o \ - $(DLL_OBJDIR)/playermonster.o \^M + $(DLL_OBJDIR)/playermonster.o \ $(DLL_OBJDIR)/python.o \ $(DLL_OBJDIR)/rat.o \ $(DLL_OBJDIR)/roach.o \ diff --git a/dlls/compile.bat b/dlls/compile.bat new file mode 100644 index 00000000..53c4511b --- /dev/null +++ b/dlls/compile.bat @@ -0,0 +1,121 @@ +@echo off +echo Setting environment for minimal Visual C++ 6 +set INCLUDE=%MSVCDir%\VC98\Include +set LIB=%MSVCDir%\VC98\Lib +set PATH=%MSVCDir%\VC98\Bin;%MSVCDir%\Common\MSDev98\Bin\;%PATH% + +echo -- Compiler is MSVC6 + +set XASH3DSRC=..\..\Xash3D_original +set INCLUDES=-I../common -I../engine -I../pm_shared -I../game_shared -I../public +set SOURCES=agrunt.cpp^ + airtank.cpp^ + aflock.cpp^ + animating.cpp^ + animation.cpp^ + apache.cpp^ + barnacle.cpp^ + barney.cpp^ + bigmomma.cpp^ + bloater.cpp^ + bmodels.cpp^ + bullsquid.cpp^ + buttons.cpp^ + cbase.cpp^ + client.cpp^ + combat.cpp^ + controller.cpp^ + crossbow.cpp^ + crowbar.cpp^ + defaultai.cpp^ + doors.cpp^ + effects.cpp^ + egon.cpp^ + explode.cpp^ + flyingmonster.cpp^ + func_break.cpp^ + func_tank.cpp^ + game.cpp^ + gamerules.cpp^ + gargantua.cpp^ + gauss.cpp^ + genericmonster.cpp^ + ggrenade.cpp^ + globals.cpp^ + glock.cpp^ + gman.cpp^ + h_ai.cpp^ + h_battery.cpp^ + h_cine.cpp^ + h_cycler.cpp^ + h_export.cpp^ + handgrenade.cpp^ + hassassin.cpp^ + headcrab.cpp^ + healthkit.cpp^ + hgrunt.cpp^ + hornet.cpp^ + hornetgun.cpp^ + houndeye.cpp^ + ichthyosaur.cpp^ + islave.cpp^ + items.cpp^ + leech.cpp^ + lights.cpp^ + maprules.cpp^ + monstermaker.cpp^ + monsters.cpp^ + monsterstate.cpp^ + mortar.cpp^ + mp5.cpp^ + multiplay_gamerules.cpp^ + nihilanth.cpp^ + nodes.cpp^ + observer.cpp^ + osprey.cpp^ + pathcorner.cpp^ + plane.cpp^ + plats.cpp^ + player.cpp^ + playermonster.cpp^ + python.cpp^ + rat.cpp^ + roach.cpp^ + rpg.cpp^ + satchel.cpp^ + schedule.cpp^ + scientist.cpp^ + scripted.cpp^ + shotgun.cpp^ + singleplay_gamerules.cpp^ + skill.cpp^ + sound.cpp^ + soundent.cpp^ + spectator.cpp^ + squadmonster.cpp^ + squeakgrenade.cpp^ + subs.cpp^ + talkmonster.cpp^ + teamplay_gamerules.cpp^ + tempmonster.cpp^ + tentacle.cpp^ + triggers.cpp^ + tripmine.cpp^ + turret.cpp^ + util.cpp^ + weapons.cpp^ + world.cpp^ + xen.cpp^ + zombie.cpp^ + ../pm_shared/pm_debug.c ../pm_shared/pm_math.c ../pm_shared/pm_shared.c +set DEFINES=/DCLIENT_WEAPONS /Dsnprintf=_snprintf /DNO_VOICEGAMEMGR +set LIBS=user32.lib +set OUTNAME=hl.dll +set DEBUG=/debug + +cl %DEFINES% %LIBS% %SOURCES% %INCLUDES% -o %OUTNAME% /link /dll /out:%OUTNAME% %DEBUG% /def:".\hl.def" + +echo -- Compile done. Cleaning... + +del *.obj *.exp *.lib *.ilk +echo -- Done. From 0d56674e28cf6d08eda6cca79ce208a16a1af6bd Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sat, 9 Dec 2017 13:49:31 +0300 Subject: [PATCH 127/211] Add steam runtime chroot method --- README.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 21db93fb..f0d3b4a1 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,21 @@ This one is the most simple but has a drawback. The drawback is that the compiled libraries will be larger in size. -#### Method 2: Create and use chroot with older distro that includes g++ 4. +#### Method 2: Build in Steam Runtime chroot + +This is the official way to build Steam compatible games for Linux. + +Clone https://github.com/ValveSoftware/steam-runtime and follow instructions https://github.com/ValveSoftware/steam-runtime#building-in-the-runtime + + sudo ./setup_chroot.sh --i386 + +Then use cmake and make as usual, but prepend the commands with `schroot --chroot steamrt_scout_i386 --`: + + mkdir build-in-steamrt && cd build-in-steamrt + schroot --chroot steamrt_scout_i386 -- cmake ../ -DGOLDSOURCE_SUPPORT=ON + schroot --chroot steamrt_scout_i386 -- make + +#### Method 3: Create your own chroot with older distro that includes g++ 4. Use the most suitable way for you to create an old distro 32-bit chroot. E.g. on Debian (and similar) you can use debootstrap. @@ -104,9 +118,10 @@ personality=linux32 Insert your actual user name in place of `yourusername`. Then prepend any make or cmake call with `schroot -c jessie --`: - schroot -c jessie -- cmake ../ -DGOLDSOURCE_SUPPORT=ON - schroot -c jessie -- make + mkdir build-in-chroot && cd build-in-chroot + schroot --chroot jessie -- cmake ../ -DGOLDSOURCE_SUPPORT=ON + schroot --chroot jessie -- make -#### Method 3: Install the needed g++ version yourself +#### Method 4: Install the needed g++ version yourself TODO: describe steps. From 87d6ca3b687eb0f6b3745c1ec79d22aac9071783 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sat, 9 Dec 2017 14:45:54 +0300 Subject: [PATCH 128/211] Add instructions for using chroot toolchain in QtCreator --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index f0d3b4a1..9261b1b3 100644 --- a/README.md +++ b/README.md @@ -125,3 +125,17 @@ Insert your actual user name in place of `yourusername`. Then prepend any make o #### Method 4: Install the needed g++ version yourself TODO: describe steps. + +#### Configuring Qt Creator to use toolchain from chroot + +Create a file with the following contents anywhere: + +```sh +#!/bin/sh +schroot --chroot steamrt_scout_i386 -- cmake "$@" +``` + +Make it executable. +In Qt Creator go to `Tools` -> `Options` -> `Build & Run` -> `CMake`. Add a new cmake tool and specify the path of previously created file. +Go to `Kits` tab, clone your default configuration and choose your CMake tool there. +Choose the new kit when opening CMakeLists.txt. From 5a60f08a59651aaaac73efa4af147f2a2d391a57 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Mon, 4 Dec 2017 01:02:25 +0300 Subject: [PATCH 129/211] Joystick support for non-sdl win32 (untested) --- cl_dll/input_goldsource.cpp | 161 ++++++++++++++++++++++++++++++++++-- 1 file changed, 153 insertions(+), 8 deletions(-) diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index 38dac71d..f530bdbc 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -217,10 +217,25 @@ enum _ControlList AxisTurn }; +#if !defined(USE_SDL2) && defined(_WIN32) +DWORD dwAxisFlags[JOY_MAX_AXES] = +{ + JOY_RETURNX, + JOY_RETURNY, + JOY_RETURNZ, + JOY_RETURNR, + JOY_RETURNU, + JOY_RETURNV +}; +#endif DWORD dwAxisMap[ JOY_MAX_AXES ]; DWORD dwControlMap[ JOY_MAX_AXES ]; +#if defined(USE_SDL2) int pdwRawValue[ JOY_MAX_AXES ]; +#elif defined(_WIN32) +PDWORD pdwRawValue[ JOY_MAX_AXES ]; +#endif DWORD joy_oldbuttonstate, joy_oldpovstate; int joy_id; @@ -228,6 +243,9 @@ DWORD joy_numbuttons; #ifdef USE_SDL2 SDL_GameController *s_pJoystick = NULL; +#elif defined(_WIN32) +DWORD joy_flags; +static JOYINFOEX ji; #endif // none of these cvars are saved over a session @@ -990,14 +1008,64 @@ void IN_StartupJoystick (void) { gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); } +#elif defined(_WIN32) + int numdevs; + JOYCAPS jc; + MMRESULT mmr; + // verify joystick driver is present + if ((numdevs = joyGetNumDevs ()) == 0) + { + gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); + return; + } + + // cycle through the joystick ids for the first valid one + for (joy_id=0 ; joy_idvalue != 0.0) + { + ji.dwUpos += 100; + } + return 1; + } + else + { + // read error occurred + // turning off the joystick seems too harsh for 1 read error,\ + // but what should be done? + // Con_Printf ("IN_ReadJoystick: no response\n"); + // joy_avail = 0; + return 0; + } +#else + return 0; +#endif } @@ -1213,7 +1353,12 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd ) for (i = 0; i < JOY_MAX_AXES; i++) { // get the floating point zero-centered, potentially-inverted data for the current axis +#ifdef USE_SDL2 fAxisValue = (float)pdwRawValue[i]; +#elif defined(_WIN32) + fAxisValue = (float) *pdwRawValue[i]; + fAxisValue -= 32768.0; +#endif if (joy_wwhack2->value != 0.0) { From 18adf0979fe6fe8a9af2e5f46721f198b6274e5e Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 10 Dec 2017 20:56:46 +0500 Subject: [PATCH 130/211] Redefine string_t. Fix wrong variables type. --- cl_dll/util_vector.h | 2 +- common/const.h | 2 +- dlls/bigmomma.cpp | 2 +- dlls/cbase.h | 2 +- dlls/effects.cpp | 6 +++--- dlls/effects.h | 2 +- dlls/extdll.h | 2 +- dlls/func_break.h | 4 ++-- dlls/func_tank.cpp | 6 +++--- dlls/lights.cpp | 2 +- dlls/mortar.cpp | 4 ++-- dlls/plats.cpp | 6 +++--- dlls/scripted.cpp | 6 +++--- dlls/scripted.h | 6 +++--- dlls/talkmonster.h | 4 ++-- dlls/triggers.cpp | 14 +++++++------- dlls/util.cpp | 14 +++++++------- dlls/util.h | 4 ++-- dlls/weapons.h | 2 +- 19 files changed, 45 insertions(+), 45 deletions(-) diff --git a/cl_dll/util_vector.h b/cl_dll/util_vector.h index ff5f9a91..8b596ac1 100644 --- a/cl_dll/util_vector.h +++ b/cl_dll/util_vector.h @@ -23,7 +23,7 @@ // Header file containing definition of globalvars_t and entvars_t typedef unsigned int func_t; // -typedef unsigned int string_t; // from engine's pr_comp.h; +typedef int string_t; // from engine's pr_comp.h; typedef float vec_t; // needed before including progdefs.h //========================================================= diff --git a/common/const.h b/common/const.h index d29816e6..3d738675 100644 --- a/common/const.h +++ b/common/const.h @@ -733,7 +733,7 @@ enum }; typedef unsigned int func_t; -typedef unsigned int string_t; +typedef int string_t; typedef unsigned char byte; typedef unsigned short word; diff --git a/dlls/bigmomma.cpp b/dlls/bigmomma.cpp index 6b594983..434d6134 100644 --- a/dlls/bigmomma.cpp +++ b/dlls/bigmomma.cpp @@ -49,7 +49,7 @@ public: virtual int Restore( CRestore &restore ); static TYPEDESCRIPTION m_SaveData[]; - int m_preSequence; + string_t m_preSequence; }; LINK_ENTITY_TO_CLASS( info_bigmomma, CInfoBM ) diff --git a/dlls/cbase.h b/dlls/cbase.h index b78de883..10f7a85f 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -438,7 +438,7 @@ class CBaseDelay : public CBaseEntity { public: float m_flDelay; - int m_iszKillTarget; + string_t m_iszKillTarget; virtual void KeyValue( KeyValueData *pkvd ); virtual int Save( CSave &save ); diff --git a/dlls/effects.cpp b/dlls/effects.cpp index 15df3bc3..5b8d650c 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -379,9 +379,10 @@ public: void BeamUpdateVars( void ); + string_t m_iszStartEntity; + string_t m_iszEndEntity; + string_t m_iszSpriteName; int m_active; - int m_iszStartEntity; - int m_iszEndEntity; float m_life; int m_boltWidth; int m_noiseAmplitude; @@ -389,7 +390,6 @@ public: int m_speed; float m_restrike; int m_spriteTexture; - int m_iszSpriteName; int m_frameStart; float m_radius; diff --git a/dlls/effects.h b/dlls/effects.h index 68f0ea29..f4b6b5b2 100644 --- a/dlls/effects.h +++ b/dlls/effects.h @@ -321,7 +321,7 @@ public: static TYPEDESCRIPTION m_SaveData[]; CSprite *m_pSprite; - int m_iszSpriteName; + string_t m_iszSpriteName; Vector m_firePosition; }; #endif //EFFECTS_H diff --git a/dlls/extdll.h b/dlls/extdll.h index 45c42309..812ce40f 100644 --- a/dlls/extdll.h +++ b/dlls/extdll.h @@ -69,7 +69,7 @@ typedef int BOOL; // Header file containing definition of globalvars_t and entvars_t typedef unsigned int func_t; -typedef unsigned int string_t; // from engine's pr_comp.h; +typedef int string_t; // from engine's pr_comp.h; typedef float vec_t; // needed before including progdefs.h // Vector class diff --git a/dlls/func_break.h b/dlls/func_break.h index ab5dda41..b4ff1fc1 100644 --- a/dlls/func_break.h +++ b/dlls/func_break.h @@ -82,9 +82,9 @@ public: Materials m_Material; Explosions m_Explosion; + string_t m_iszGibModel; + string_t m_iszSpawnObject; int m_idShard; float m_angle; - int m_iszGibModel; - int m_iszSpawnObject; }; #endif // FUNC_BREAK_H diff --git a/dlls/func_tank.cpp b/dlls/func_tank.cpp index 6eebc675..013948eb 100644 --- a/dlls/func_tank.cpp +++ b/dlls/func_tank.cpp @@ -97,6 +97,9 @@ public: protected: CBasePlayer* m_pController; + string_t m_iszSpriteSmoke; + string_t m_iszSpriteFlash; + string_t m_iszMaster; // Master entity (game_team_master or multisource) float m_flNextAttack; Vector m_vecControllerUsePos; @@ -120,14 +123,11 @@ protected: Vector m_barrelPos; // Length of the freakin barrel float m_spriteScale; // Scale of any sprites we shoot - int m_iszSpriteSmoke; - int m_iszSpriteFlash; TANKBULLET m_bulletType; // Bullet type int m_iBulletDamage; // 0 means use Bullet type's default damage Vector m_sightOrigin; // Last sight of target int m_spread; // firing spread - int m_iszMaster; // Master entity (game_team_master or multisource) }; TYPEDESCRIPTION CFuncTank::m_SaveData[] = diff --git a/dlls/lights.cpp b/dlls/lights.cpp index e6b03125..8a4f8de8 100644 --- a/dlls/lights.cpp +++ b/dlls/lights.cpp @@ -37,8 +37,8 @@ public: static TYPEDESCRIPTION m_SaveData[]; private: + string_t m_iszPattern; int m_iStyle; - int m_iszPattern; }; LINK_ENTITY_TO_CLASS( light, CLight ) diff --git a/dlls/mortar.cpp b/dlls/mortar.cpp index 33a7d2da..7faf3e56 100644 --- a/dlls/mortar.cpp +++ b/dlls/mortar.cpp @@ -45,8 +45,8 @@ public: void EXPORT FieldUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - int m_iszXController; - int m_iszYController; + string_t m_iszXController; + string_t m_iszYController; float m_flSpread; float m_flDelay; int m_iCount; diff --git a/dlls/plats.cpp b/dlls/plats.cpp index c1220f3c..b3e1c683 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -1619,9 +1619,9 @@ public: CFuncTrackTrain *m_train; - int m_trackTopName; - int m_trackBottomName; - int m_trainName; + string_t m_trackTopName; + string_t m_trackBottomName; + string_t m_trainName; TRAIN_CODE m_code; int m_targetState; int m_use; diff --git a/dlls/scripted.cpp b/dlls/scripted.cpp index 678502f6..92b9aa6a 100644 --- a/dlls/scripted.cpp +++ b/dlls/scripted.cpp @@ -907,15 +907,15 @@ public: BOOL StartSentence( CBaseMonster *pTarget ); private: - int m_iszSentence; // string index for idle animation - int m_iszEntity; // entity that is wanted for this sentence + string_t m_iszSentence; // string index for idle animation + string_t m_iszEntity; // entity that is wanted for this sentence + string_t m_iszListener; // name of entity to look at while talking float m_flRadius; // range to search float m_flDuration; // How long the sentence lasts float m_flRepeat; // repeat rate float m_flAttenuation; float m_flVolume; BOOL m_active; - int m_iszListener; // name of entity to look at while talking }; #define SF_SENTENCE_ONCE 0x0001 diff --git a/dlls/scripted.h b/dlls/scripted.h index 25348114..6cf8cfa1 100644 --- a/dlls/scripted.h +++ b/dlls/scripted.h @@ -77,9 +77,9 @@ public: void AllowInterrupt( BOOL fAllow ); int IgnoreConditions( void ); - int m_iszIdle; // string index for idle animation - int m_iszPlay; // string index for scripted animation - int m_iszEntity; // entity that is wanted for this script + string_t m_iszIdle; // string index for idle animation + string_t m_iszPlay; // string index for scripted animation + string_t m_iszEntity; // entity that is wanted for this script int m_fMoveTo; int m_iFinishSchedule; float m_flRadius; // range to search diff --git a/dlls/talkmonster.h b/dlls/talkmonster.h index 72222aae..084861bc 100644 --- a/dlls/talkmonster.h +++ b/dlls/talkmonster.h @@ -162,8 +162,8 @@ public: int m_voicePitch; // pitch of voice for this head const char *m_szGrp[TLK_CGROUPS]; // sentence group names float m_useTime; // Don't allow +USE until this time - int m_iszUse; // Custom +USE sentence group (follow) - int m_iszUnUse; // Custom +USE sentence group (stop following) + string_t m_iszUse; // Custom +USE sentence group (follow) + string_t m_iszUnUse; // Custom +USE sentence group (stop following) float m_flLastSaidSmelled;// last time we talked about something that stinks float m_flStopTalkTime;// when in the future that I'll be done saying this sentence. diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index 8171a195..7d7f255c 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -114,7 +114,7 @@ public: static TYPEDESCRIPTION m_SaveData[]; private: - int m_globalstate; + string_t m_globalstate; USE_TYPE triggerType; }; @@ -267,11 +267,11 @@ public: static TYPEDESCRIPTION m_SaveData[]; - int m_cTargets; // the total number of targets in this manager's fire list. + string_t m_iTargetName[MAX_MULTI_TARGETS];// list if indexes into global string array + float m_flTargetDelay[MAX_MULTI_TARGETS];// delay (in seconds) from time of manager fire to target fire + int m_cTargets; // the total number of targets in this manager's fire list. int m_index; // Current target float m_startTime;// Time we started firing - int m_iTargetName[MAX_MULTI_TARGETS];// list if indexes into global string array - float m_flTargetDelay[MAX_MULTI_TARGETS];// delay (in seconds) from time of manager fire to target fire private: inline BOOL IsClone( void ) { return ( pev->spawnflags & SF_MULTIMAN_CLONE ) ? TRUE : FALSE; } inline BOOL ShouldClone( void ) @@ -1321,9 +1321,9 @@ public: static TYPEDESCRIPTION m_SaveData[]; + string_t m_changeTarget; char m_szMapName[cchMapNameMost]; // trigger_changelevel only: next map char m_szLandmarkName[cchMapNameMost]; // trigger_changelevel only: landmark on next map - int m_changeTarget; float m_changeTargetDelay; }; @@ -2054,7 +2054,7 @@ public: static TYPEDESCRIPTION m_SaveData[]; private: - int m_iszNewTarget; + string_t m_iszNewTarget; }; LINK_ENTITY_TO_CLASS( trigger_changetarget, CTriggerChangeTarget ) @@ -2117,7 +2117,7 @@ public: EHANDLE m_hPlayer; EHANDLE m_hTarget; CBaseEntity *m_pentPath; - int m_sPath; + string_t m_sPath; float m_flWait; float m_flReturnTime; float m_flStopTime; diff --git a/dlls/util.cpp b/dlls/util.cpp index f382ac58..94c8c68c 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1586,7 +1586,7 @@ void UTIL_StripToken( const char *pKey, char *pDest ) static int gSizes[FIELD_TYPECOUNT] = { sizeof(float), // FIELD_FLOAT - sizeof(int), // FIELD_STRING + sizeof(string_t), // FIELD_STRING sizeof(void*), // FIELD_ENTITY sizeof(void*), // FIELD_CLASSPTR sizeof(void*), // FIELD_EHANDLE @@ -1613,7 +1613,7 @@ static int gSizes[FIELD_TYPECOUNT] = static int gInputSizes[FIELD_TYPECOUNT] = { sizeof(float), // FIELD_FLOAT - sizeof(int), // FIELD_STRING + sizeof(string_t), // FIELD_STRING sizeof(int), // FIELD_ENTITY sizeof(int), // FIELD_CLASSPTR sizeof(int), // FIELD_EHANDLE @@ -1940,7 +1940,7 @@ void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ) case FIELD_MODELNAME: case FIELD_SOUNDNAME: case FIELD_STRING: - ( *(int *)( (char *)pev + pField->fieldOffset ) ) = ALLOC_STRING( pkvd->szValue ); + ( *(string_t *)( (char *)pev + pField->fieldOffset ) ) = ALLOC_STRING( pkvd->szValue ); break; case FIELD_TIME: case FIELD_FLOAT: @@ -2014,7 +2014,7 @@ int CSave::WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFi case FIELD_MODELNAME: case FIELD_SOUNDNAME: case FIELD_STRING: - WriteString( pTest->fieldName, (int *)pOutputData, pTest->fieldSize ); + WriteString( pTest->fieldName, (string_t *)pOutputData, pTest->fieldSize ); break; case FIELD_CLASSPTR: case FIELD_EVARS: @@ -2197,14 +2197,14 @@ int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCou } pInputData = pString; if( strlen( (char *)pInputData ) == 0 ) - *( (int *)pOutputData ) = 0; + *( (string_t *)pOutputData ) = 0; else { - int string; + string_t string; string = ALLOC_STRING( (char *)pInputData ); - *( (int *)pOutputData ) = string; + *( (string_t *)pOutputData ) = string; if( !FStringNull( string ) && m_precache ) { diff --git a/dlls/util.h b/dlls/util.h index 2ffe536e..ee7d116b 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -37,13 +37,13 @@ extern globalvars_t *gpGlobals; #define STRING(offset) (const char *)(gpGlobals->pStringBase + (int)offset) #if !defined XASH_64BIT || defined(CLIENT_DLL) -#define MAKE_STRING(str) ((size_t)str - (size_t)STRING(0)) +#define MAKE_STRING(str) ((int)str - (int)STRING(0)) #else static inline int MAKE_STRING(const char *szValue) { long long ptrdiff = szValue - STRING(0); if( ptrdiff > INT_MAX || ptrdiff < INT_MIN ) - return ALLOC_STRING(szValue); + return ALLOC_STRING( szValue ); else return (int)ptrdiff; } diff --git a/dlls/weapons.h b/dlls/weapons.h index 6c03105b..0cfa2031 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -446,7 +446,7 @@ public: CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES];// one slot for each - int m_rgiszAmmo[MAX_AMMO_SLOTS];// ammo names + string_t m_rgiszAmmo[MAX_AMMO_SLOTS];// ammo names int m_rgAmmo[MAX_AMMO_SLOTS];// ammo quantities int m_cAmmoTypes;// how many ammo types packed into this box (if packed by a level designer) From 28020503292fb16cf30b6ccd639f5e6cb9cd4b46 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 10 Dec 2017 21:05:13 +0500 Subject: [PATCH 131/211] Add missing break. --- dlls/hgrunt.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dlls/hgrunt.cpp b/dlls/hgrunt.cpp index 4cb85c2c..62c947f1 100644 --- a/dlls/hgrunt.cpp +++ b/dlls/hgrunt.cpp @@ -959,6 +959,7 @@ void CHGrunt::HandleAnimEvent( MonsterEvent_t *pEvent ) } } + break; default: CSquadMonster::HandleAnimEvent( pEvent ); break; From 83c0505ffe12da025c207fcca1f9bd67b5291097 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 10 Dec 2017 21:08:10 +0500 Subject: [PATCH 132/211] Add missing precache calls. --- dlls/effects.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/effects.cpp b/dlls/effects.cpp index 5b8d650c..2e127b2d 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -2181,6 +2181,8 @@ public: void CItemSoda::Precache( void ) { + PRECACHE_MODEL( "models/can.mdl" ); + PRECACHE_SOUND( "weapons/g_bounce.wav" ); } LINK_ENTITY_TO_CLASS( item_sodacan, CItemSoda ) From 41c9b072e5f871f6d4ce778a037cfa6ae38abcdb Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 10 Dec 2017 22:19:34 +0500 Subject: [PATCH 133/211] Add missing #include guards. --- cl_dll/ammohistory.h | 3 +++ cl_dll/health.h | 3 +++ cl_dll/hud_spectator.h | 4 ++-- cl_dll/parsemsg.h | 3 +++ dlls/gamerules.h | 4 +++- dlls/plane.h | 6 +++--- dlls/skill.h | 3 +++ dlls/spectator.h | 3 +++ dlls/squad.h | 4 +++- dlls/squadmonster.h | 3 +++ dlls/util.h | 3 +++ 11 files changed, 32 insertions(+), 7 deletions(-) diff --git a/cl_dll/ammohistory.h b/cl_dll/ammohistory.h index f1063ae1..032d3ee3 100644 --- a/cl_dll/ammohistory.h +++ b/cl_dll/ammohistory.h @@ -15,6 +15,8 @@ // // ammohistory.h // +#ifndef AMMOHISTORY_H +#define AMMOHISTORY_H // this is the max number of items in each bucket #define MAX_WEAPON_POSITIONS MAX_WEAPON_SLOTS @@ -137,3 +139,4 @@ public: }; extern HistoryResource gHR; +#endif // AMMOHISTORY_H diff --git a/cl_dll/health.h b/cl_dll/health.h index 132b9cb4..1007c17c 100644 --- a/cl_dll/health.h +++ b/cl_dll/health.h @@ -12,6 +12,8 @@ * without written permission from Valve LLC. * ****/ +#ifndef HEALTH_H +#define HEALTH_H #define DMG_IMAGE_LIFE 2 // seconds that image is up @@ -122,3 +124,4 @@ private: void CalcDamageDirection( vec3_t vecFrom ); void UpdateTiles( float fTime, long bits ); }; +#endif // HEALTH_H diff --git a/cl_dll/hud_spectator.h b/cl_dll/hud_spectator.h index 58026668..9cfc5519 100644 --- a/cl_dll/hud_spectator.h +++ b/cl_dll/hud_spectator.h @@ -5,8 +5,8 @@ // $NoKeywords: $ //============================================================================= -#ifndef SPECTATOR_H -#define SPECTATOR_H +#ifndef HUD_SPECTATOR_H +#define HUD_SPECTATOR_H #pragma once #include "cl_entity.h" diff --git a/cl_dll/parsemsg.h b/cl_dll/parsemsg.h index 0e6bd2a3..6d552413 100644 --- a/cl_dll/parsemsg.h +++ b/cl_dll/parsemsg.h @@ -15,6 +15,8 @@ // // parsemsg.h // +#ifndef PARSEMSG_H +#define PARSEMSG_H #define ASSERT( x ) @@ -30,6 +32,7 @@ float READ_COORD( void ); float READ_ANGLE( void ); float READ_HIRESANGLE( void ); +#endif // PARSEMSG_H diff --git a/dlls/gamerules.h b/dlls/gamerules.h index 6ad470d0..71036151 100644 --- a/dlls/gamerules.h +++ b/dlls/gamerules.h @@ -15,7 +15,8 @@ //========================================================= // GameRules //========================================================= - +#ifndef GAMERULES_H +#define GAMERULES_H //#include "weapons.h" //#include "items.h" class CBasePlayerItem; @@ -361,3 +362,4 @@ protected: }; extern DLL_GLOBAL CGameRules *g_pGameRules; +#endif // GAMERULES_H diff --git a/dlls/plane.h b/dlls/plane.h index 35a17611..912062f6 100644 --- a/dlls/plane.h +++ b/dlls/plane.h @@ -12,12 +12,12 @@ * without written permission from Valve LLC. * ****/ -#ifndef PLANE_H -#define PLANE_H - //========================================================= // Plane //========================================================= +#ifndef PLANE_H +#define PLANE_H + class CPlane { public: diff --git a/dlls/skill.h b/dlls/skill.h index 12b784e3..aa338362 100644 --- a/dlls/skill.h +++ b/dlls/skill.h @@ -15,6 +15,8 @@ //========================================================= // skill.h - skill level concerns //========================================================= +#ifndef SKILL_H +#define SKILL_H struct skilldata_t { @@ -143,3 +145,4 @@ extern DLL_GLOBAL int g_iSkillLevel; #define SKILL_EASY 1 #define SKILL_MEDIUM 2 #define SKILL_HARD 3 +#endif // SKILL_H diff --git a/dlls/spectator.h b/dlls/spectator.h index 90f8678f..00567fc6 100644 --- a/dlls/spectator.h +++ b/dlls/spectator.h @@ -13,6 +13,8 @@ * ****/ // Spectator.h +#ifndef SPECTATOR_H +#define SPECTATOR_H class CBaseSpectator : public CBaseEntity { @@ -25,3 +27,4 @@ public: private: void SpectatorImpulseCommand( void ); }; +#endif // SPECTATOR_H diff --git a/dlls/squad.h b/dlls/squad.h index bb2784bb..c29a7199 100644 --- a/dlls/squad.h +++ b/dlls/squad.h @@ -4,10 +4,11 @@ // // $NoKeywords: $ //============================================================================= - //========================================================= // squad.h //========================================================= +#ifndef SQUAD_H +#define SQUAD_H // these are special group roles that are assigned to members when the group is formed. // the reason these are explicitly assigned and tasks like throwing grenades to flush out @@ -19,3 +20,4 @@ #define bits_SQUAD_FLANK_RIGHT ( 1 << 1 ) #define bits_SQUAD_ADVANCE ( 1 << 2 ) #define bits_SQUAD_FLUSH_ATTACK ( 1 << 3 ) +#endif // SQUAD_H diff --git a/dlls/squadmonster.h b/dlls/squadmonster.h index 707910c2..132d4177 100644 --- a/dlls/squadmonster.h +++ b/dlls/squadmonster.h @@ -16,6 +16,8 @@ // CSquadMonster - all the extra data for monsters that // form squads. //========================================================= +#ifndef SQUADMONSTER_H +#define SQUADMONSTER_H #define SF_SQUADMONSTER_LEADER 32 @@ -116,3 +118,4 @@ public: MONSTERSTATE GetIdealState( void ); Schedule_t *GetScheduleOfType( int iType ); }; +#endif // SQUADMONSTER_H diff --git a/dlls/util.h b/dlls/util.h index ee7d116b..8f56cd76 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -12,6 +12,8 @@ * without written permission from Valve LLC. * ****/ +#ifndef UTIL_H +#define UTIL_H // // Misc utility code // @@ -575,3 +577,4 @@ int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ); float UTIL_WeaponTimeBase( void ); +#endif // UTIL_H From f27d1028acf7ae1cf7494002e880d235177f2c52 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 11 Dec 2017 01:40:41 +0500 Subject: [PATCH 134/211] Do not reorganize variables in classes. Add missing #pragma once directives and more #include guards. --- cl_dll/GameStudioModelRenderer.h | 6 ++---- cl_dll/GameStudioModelRenderer_Sample.h | 6 ++---- cl_dll/StudioModelRenderer.h | 4 +--- cl_dll/ammo.h | 2 +- cl_dll/ammohistory.h | 1 + cl_dll/camera.h | 2 +- cl_dll/cl_dll.h | 1 + cl_dll/com_weapons.h | 4 +--- cl_dll/demo.h | 2 +- cl_dll/ev_hldm.h | 1 + cl_dll/eventscripts.h | 1 + cl_dll/health.h | 1 + cl_dll/hud.h | 1 + cl_dll/hud_iface.h | 2 +- cl_dll/hud_spectator.h | 2 +- cl_dll/in_defs.h | 2 +- cl_dll/input_mouse.h | 1 + cl_dll/kbutton.h | 3 +-- cl_dll/overview.h | 2 +- cl_dll/parsemsg.h | 1 + cl_dll/studio_util.h | 4 +--- cl_dll/util_vector.h | 4 ++++ common/beamdef.h | 4 ++-- common/bspfile.h | 2 +- common/cl_entity.h | 4 ++-- common/com_model.h | 4 ++-- common/con_nprint.h | 3 ++- common/const.h | 1 + common/cvardef.h | 1 + common/demo_api.h | 4 ++-- common/dlight.h | 4 ++-- common/entity_state.h | 3 ++- common/entity_types.h | 4 ++-- common/event_api.h | 4 ++-- common/event_args.h | 3 ++- common/event_flags.h | 4 ++-- common/gameinfo.h | 4 ++-- common/hltv.h | 4 ++-- common/ivoicetweak.h | 4 ++-- common/lightstyle.h | 4 ++-- common/mathlib.h | 5 ++++- common/net_api.h | 4 ++-- common/netadr.h | 4 ++-- common/particledef.h | 4 ++-- common/pmtrace.h | 4 ++-- common/qfont.h | 4 ++-- common/r_efx.h | 4 ++-- common/r_studioint.h | 5 ++--- common/ref_params.h | 4 ++-- common/render_api.h | 4 ++-- common/screenfade.h | 4 ++-- common/studio_event.h | 4 ++-- common/triangleapi.h | 2 +- common/usercmd.h | 4 ++-- common/wadfile.h | 4 ++-- common/weaponinfo.h | 4 ++-- common/wrect.h | 4 ++-- dlls/activity.h | 2 +- dlls/activitymap.h | 5 ++++- dlls/animation.h | 1 + dlls/basemonster.h | 2 +- dlls/cbase.h | 1 + dlls/cdll_dll.h | 2 +- dlls/client.h | 1 + dlls/decals.h | 1 + dlls/doors.h | 1 + dlls/effects.cpp | 4 ++-- dlls/effects.h | 1 + dlls/explode.h | 3 ++- dlls/exportdef.h | 1 + dlls/extdll.h | 1 + dlls/flyingmonster.h | 2 +- dlls/func_break.h | 5 +++-- dlls/func_tank.cpp | 6 +++--- dlls/game.h | 2 +- dlls/gamerules.h | 1 + dlls/hornet.h | 5 ++++- dlls/items.h | 1 + dlls/lights.cpp | 2 +- dlls/monsters.h | 1 + dlls/nodes.h | 1 + dlls/physcallback.h | 2 +- dlls/player.h | 1 + dlls/saverestore.h | 1 + dlls/schedule.h | 2 +- dlls/scripted.cpp | 2 +- dlls/scripted.h | 1 + dlls/scriptevent.h | 3 ++- dlls/skill.h | 3 ++- dlls/soundent.h | 4 ++++ dlls/spectator.h | 1 + dlls/squad.h | 1 + dlls/squadmonster.h | 1 + dlls/talkmonster.h | 1 + dlls/teamplay_gamerules.h | 4 ++++ dlls/trains.h | 1 + dlls/triggers.cpp | 6 +++--- dlls/util.h | 1 + dlls/vector.h | 1 + dlls/weapons.h | 1 + engine/cdll_exp.h | 3 ++- engine/cdll_int.h | 2 +- engine/custom.h | 3 +-- engine/customentity.h | 2 +- engine/edict.h | 4 +--- engine/eiface.h | 2 +- engine/keydefs.h | 4 ++-- engine/menu_int.h | 2 +- engine/physint.h | 4 ++-- engine/progdefs.h | 3 +-- engine/shake.h | 2 +- engine/sprite.h | 4 ++-- engine/studio.h | 2 +- pm_shared/pm_debug.h | 3 +-- pm_shared/pm_defs.h | 3 +-- pm_shared/pm_info.h | 3 +-- pm_shared/pm_materials.h | 1 + pm_shared/pm_movevars.h | 1 + pm_shared/pm_shared.h | 4 +--- 119 files changed, 183 insertions(+), 140 deletions(-) diff --git a/cl_dll/GameStudioModelRenderer.h b/cl_dll/GameStudioModelRenderer.h index 7d06f70f..881dd144 100644 --- a/cl_dll/GameStudioModelRenderer.h +++ b/cl_dll/GameStudioModelRenderer.h @@ -5,11 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #if !defined( GAMESTUDIOMODELRENDERER_H ) #define GAMESTUDIOMODELRENDERER_H -#if defined( _WIN32 ) -#pragma once -#endif /* ==================== @@ -23,4 +21,4 @@ public: CGameStudioModelRenderer( void ); }; -#endif // GAMESTUDIOMODELRENDERER_H \ No newline at end of file +#endif // GAMESTUDIOMODELRENDERER_H diff --git a/cl_dll/GameStudioModelRenderer_Sample.h b/cl_dll/GameStudioModelRenderer_Sample.h index c924ba3e..9c09374b 100644 --- a/cl_dll/GameStudioModelRenderer_Sample.h +++ b/cl_dll/GameStudioModelRenderer_Sample.h @@ -5,11 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #if !defined( GAMESTUDIOMODELRENDERER_H ) #define GAMESTUDIOMODELRENDERER_H -#if defined( _WIN32 ) -#pragma once -#endif /* ==================== @@ -52,4 +50,4 @@ private: bool m_bLocal; }; -#endif // GAMESTUDIOMODELRENDERER_H \ No newline at end of file +#endif // GAMESTUDIOMODELRENDERER_H diff --git a/cl_dll/StudioModelRenderer.h b/cl_dll/StudioModelRenderer.h index 0a56b731..cbfd0d3b 100644 --- a/cl_dll/StudioModelRenderer.h +++ b/cl_dll/StudioModelRenderer.h @@ -5,11 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #if !defined ( STUDIOMODELRENDERER_H ) #define STUDIOMODELRENDERER_H -#if defined( _WIN32 ) -#pragma once -#endif /* ==================== diff --git a/cl_dll/ammo.h b/cl_dll/ammo.h index 9134681c..57c08805 100644 --- a/cl_dll/ammo.h +++ b/cl_dll/ammo.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef __AMMO_H__ #define __AMMO_H__ diff --git a/cl_dll/ammohistory.h b/cl_dll/ammohistory.h index 032d3ee3..44edc916 100644 --- a/cl_dll/ammohistory.h +++ b/cl_dll/ammohistory.h @@ -15,6 +15,7 @@ // // ammohistory.h // +#pragma once #ifndef AMMOHISTORY_H #define AMMOHISTORY_H diff --git a/cl_dll/camera.h b/cl_dll/camera.h index 448b22ca..69a00216 100644 --- a/cl_dll/camera.h +++ b/cl_dll/camera.h @@ -7,7 +7,7 @@ // Camera.h -- defines and such for a 3rd person camera // NOTE: must include quakedef.h first - +#pragma once #ifndef _CAMERA_H_ #define _CAMERA_H_ diff --git a/cl_dll/cl_dll.h b/cl_dll/cl_dll.h index 0acd6860..6e1c4e69 100644 --- a/cl_dll/cl_dll.h +++ b/cl_dll/cl_dll.h @@ -25,6 +25,7 @@ // - Drawing the HUD graphics every frame // - Handling the custum HUD-update packets // +#pragma once #ifndef CL_DLL_H #define CL_DLL_H typedef unsigned char byte; diff --git a/cl_dll/com_weapons.h b/cl_dll/com_weapons.h index d252c196..efe06ad6 100644 --- a/cl_dll/com_weapons.h +++ b/cl_dll/com_weapons.h @@ -7,11 +7,9 @@ // com_weapons.h // Shared weapons common function prototypes +#pragma once #if !defined( COM_WEAPONSH ) #define COM_WEAPONSH -#ifdef _WIN32 -#pragma once -#endif #include "hud_iface.h" diff --git a/cl_dll/demo.h b/cl_dll/demo.h index a0a1b30e..b7dbaff0 100644 --- a/cl_dll/demo.h +++ b/cl_dll/demo.h @@ -5,9 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #if !defined( DEMOH ) #define DEMOH -#pragma once // Types of demo messages we can write/parse enum diff --git a/cl_dll/ev_hldm.h b/cl_dll/ev_hldm.h index bff43b1e..88b221df 100644 --- a/cl_dll/ev_hldm.h +++ b/cl_dll/ev_hldm.h @@ -5,6 +5,7 @@ // $NoKeywords: $ //============================================================================= +#pragma once #if !defined ( EV_HLDMH ) #define EV_HLDMH diff --git a/cl_dll/eventscripts.h b/cl_dll/eventscripts.h index bb835474..c11ee338 100644 --- a/cl_dll/eventscripts.h +++ b/cl_dll/eventscripts.h @@ -6,6 +6,7 @@ //============================================================================= // eventscripts.h +#pragma once #if !defined ( EVENTSCRIPTSH ) #define EVENTSCRIPTSH diff --git a/cl_dll/health.h b/cl_dll/health.h index 1007c17c..62d7e0bc 100644 --- a/cl_dll/health.h +++ b/cl_dll/health.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef HEALTH_H #define HEALTH_H diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 1970753d..decfa917 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -19,6 +19,7 @@ // // CHud handles the message, calculation, and drawing the HUD // +#pragma once #ifndef HUD_H #define HUD_H #define RGB_YELLOWISH 0x00FFA000 //255,160,0 diff --git a/cl_dll/hud_iface.h b/cl_dll/hud_iface.h index a7a05e7e..7993bd9d 100644 --- a/cl_dll/hud_iface.h +++ b/cl_dll/hud_iface.h @@ -5,9 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #if !defined( HUD_IFACEH ) #define HUD_IFACEH -#pragma once #include "exportdef.h" diff --git a/cl_dll/hud_spectator.h b/cl_dll/hud_spectator.h index 9cfc5519..7a9ec9d3 100644 --- a/cl_dll/hud_spectator.h +++ b/cl_dll/hud_spectator.h @@ -5,9 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #ifndef HUD_SPECTATOR_H #define HUD_SPECTATOR_H -#pragma once #include "cl_entity.h" diff --git a/cl_dll/in_defs.h b/cl_dll/in_defs.h index 037c7cc6..d5c352fa 100644 --- a/cl_dll/in_defs.h +++ b/cl_dll/in_defs.h @@ -5,9 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #if !defined( IN_DEFSH ) #define IN_DEFSH -#pragma once // up / down #define PITCH 0 diff --git a/cl_dll/input_mouse.h b/cl_dll/input_mouse.h index 6ddf54db..cf0102c8 100644 --- a/cl_dll/input_mouse.h +++ b/cl_dll/input_mouse.h @@ -1,3 +1,4 @@ +#pragma once #ifndef INPUT_MOUSE_H #define INPUT_MOUSE_H #include "cl_dll.h" diff --git a/cl_dll/kbutton.h b/cl_dll/kbutton.h index 29accdf5..54f1ea93 100644 --- a/cl_dll/kbutton.h +++ b/cl_dll/kbutton.h @@ -4,10 +4,9 @@ // // $NoKeywords: $ //============================================================================= - +#pragma once #if !defined( KBUTTONH ) #define KBUTTONH -#pragma once typedef struct kbutton_s { diff --git a/cl_dll/overview.h b/cl_dll/overview.h index 6748760b..59535fb4 100644 --- a/cl_dll/overview.h +++ b/cl_dll/overview.h @@ -5,9 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #ifndef OVERVIEW_H #define OVERVIEW_H -#pragma once //----------------------------------------------------------------------------- // Purpose: Handles the drawing of the top-down map and all the things on it diff --git a/cl_dll/parsemsg.h b/cl_dll/parsemsg.h index 6d552413..05efefc3 100644 --- a/cl_dll/parsemsg.h +++ b/cl_dll/parsemsg.h @@ -15,6 +15,7 @@ // // parsemsg.h // +#pragma once #ifndef PARSEMSG_H #define PARSEMSG_H diff --git a/cl_dll/studio_util.h b/cl_dll/studio_util.h index 963dcda7..7af94672 100644 --- a/cl_dll/studio_util.h +++ b/cl_dll/studio_util.h @@ -5,11 +5,9 @@ // $NoKeywords: $ //============================================================================= +#pragma once #if !defined( STUDIO_UTIL_H ) #define STUDIO_UTIL_H -#if defined( WIN32 ) -#pragma once -#endif #ifndef M_PI #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h diff --git a/cl_dll/util_vector.h b/cl_dll/util_vector.h index 8b596ac1..477d97be 100644 --- a/cl_dll/util_vector.h +++ b/cl_dll/util_vector.h @@ -15,6 +15,9 @@ // Vector.h // A subset of the extdll.h in the project HL Entity DLL // +#pragma once +#ifndef UTIL_VECTOR_H +#define UTIL_VECTOR_H // Misc C-runtime library headers #include "stdio.h" @@ -124,3 +127,4 @@ inline float DotProduct( const Vector& a, const Vector& b) { return( a.x * b.x + inline Vector CrossProduct(const Vector& a, const Vector& b) { return Vector( a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x ); } #define vec3_t Vector +#endif // UTIL_VECTOR_H diff --git a/common/beamdef.h b/common/beamdef.h index 3b8c553a..f254428c 100644 --- a/common/beamdef.h +++ b/common/beamdef.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef BEAMDEF_H #define BEAMDEF_H @@ -57,4 +57,4 @@ struct beam_s struct particle_s *particles; }; -#endif//BEAMDEF_H \ No newline at end of file +#endif//BEAMDEF_H diff --git a/common/bspfile.h b/common/bspfile.h index 809e2fd0..079e1b21 100644 --- a/common/bspfile.h +++ b/common/bspfile.h @@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ - +#pragma once #ifndef BSPFILE_H #define BSPFILE_H diff --git a/common/cl_entity.h b/common/cl_entity.h index 02f84e35..c003ce30 100644 --- a/common/cl_entity.h +++ b/common/cl_entity.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef CL_ENTITY_H #define CL_ENTITY_H @@ -102,4 +102,4 @@ struct cl_entity_s colorVec cvFloorColor; }; -#endif//CL_ENTITY_H \ No newline at end of file +#endif//CL_ENTITY_H diff --git a/common/com_model.h b/common/com_model.h index 709f23d9..abc8e8e6 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ - +#pragma once #ifndef COM_MODEL_H #define COM_MODEL_H @@ -410,4 +410,4 @@ typedef struct mspriteframedesc_t frames[1]; } msprite_t; -#endif//COM_MODEL_H \ No newline at end of file +#endif//COM_MODEL_H diff --git a/common/con_nprint.h b/common/con_nprint.h index 5d87c760..615a1850 100644 --- a/common/con_nprint.h +++ b/common/con_nprint.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef CON_NPRINT_H #define CON_NPRINT_H @@ -22,4 +23,4 @@ typedef struct con_nprint_s float color[3]; // RGB colors ( 0.0 -> 1.0 scale ) } con_nprint_t; -#endif//CON_NPRINT_H \ No newline at end of file +#endif//CON_NPRINT_H diff --git a/common/const.h b/common/const.h index 3d738675..fa0f33e6 100644 --- a/common/const.h +++ b/common/const.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef CONST_H #define CONST_H // diff --git a/common/cvardef.h b/common/cvardef.h index e8a24581..f461c329 100644 --- a/common/cvardef.h +++ b/common/cvardef.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef CVARDEF_H #define CVARDEF_H diff --git a/common/demo_api.h b/common/demo_api.h index fa89bbef..1a678b60 100644 --- a/common/demo_api.h +++ b/common/demo_api.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef DEMO_API_H #define DEMO_API_H @@ -24,4 +24,4 @@ typedef struct demo_api_s void (*WriteBuffer)( int size, unsigned char *buffer ); } demo_api_t; -#endif//DEMO_API_H \ No newline at end of file +#endif//DEMO_API_H diff --git a/common/dlight.h b/common/dlight.h index b139d582..ecb01445 100644 --- a/common/dlight.h +++ b/common/dlight.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef DLIGHT_H #define DLIGHT_H @@ -28,4 +28,4 @@ typedef struct dlight_s qboolean dark; // subtracts light instead of adding } dlight_t; -#endif//DLIGHT_H \ No newline at end of file +#endif//DLIGHT_H diff --git a/common/entity_state.h b/common/entity_state.h index ef5448f1..2ffd70dc 100644 --- a/common/entity_state.h +++ b/common/entity_state.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef ENTITY_STATE_H #define ENTITY_STATE_H @@ -183,4 +184,4 @@ typedef struct local_state_s weapon_data_t weapondata[64]; } local_state_t; -#endif//ENTITY_STATE_H \ No newline at end of file +#endif//ENTITY_STATE_H diff --git a/common/entity_types.h b/common/entity_types.h index 25a8fce9..f5754fea 100644 --- a/common/entity_types.h +++ b/common/entity_types.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef ENTITY_TYPES_H #define ENTITY_TYPES_H @@ -22,4 +22,4 @@ #define ET_BEAM 3 #define ET_FRAGMENTED 4 // BMODEL or SPRITE that was split across BSP nodes -#endif//ENTITY_TYPES_H \ No newline at end of file +#endif//ENTITY_TYPES_H diff --git a/common/event_api.h b/common/event_api.h index a7ff71b2..86c5fbe9 100644 --- a/common/event_api.h +++ b/common/event_api.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef EVENT_API_H #define EVENT_API_H @@ -51,4 +51,4 @@ typedef struct event_api_s struct msurface_s *( *EV_TraceSurface )( int ground, float *vstart, float *vend ); } event_api_t; -#endif//EVENT_API_H \ No newline at end of file +#endif//EVENT_API_H diff --git a/common/event_args.h b/common/event_args.h index d85906cc..4cf63741 100644 --- a/common/event_args.h +++ b/common/event_args.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef EVENT_ARGS_H #define EVENT_ARGS_H @@ -44,4 +45,4 @@ typedef struct event_args_s int bparam2; } event_args_t; -#endif//EVENT_ARGS_H \ No newline at end of file +#endif//EVENT_ARGS_H diff --git a/common/event_flags.h b/common/event_flags.h index 3c1d8fb3..a2d5f3b7 100644 --- a/common/event_flags.h +++ b/common/event_flags.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef EVENT_FLAGS_H #define EVENT_FLAGS_H @@ -42,4 +42,4 @@ // Only issue event client side ( from shared code ) #define FEV_CLIENT (1<<6) -#endif//EVENT_FLAGS_H \ No newline at end of file +#endif//EVENT_FLAGS_H diff --git a/common/gameinfo.h b/common/gameinfo.h index 511b3718..ab5f649c 100644 --- a/common/gameinfo.h +++ b/common/gameinfo.h @@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ - +#pragma once #ifndef GAMEINFO_H #define GAMEINFO_H @@ -46,4 +46,4 @@ typedef struct int gamemode; } GAMEINFO; -#endif//GAMEINFO_H \ No newline at end of file +#endif//GAMEINFO_H diff --git a/common/hltv.h b/common/hltv.h index 79251910..e64dd30b 100644 --- a/common/hltv.h +++ b/common/hltv.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef HLTV_H #define HLTV_H @@ -56,4 +56,4 @@ #define MAX_DIRECTOR_CMD_PARAMETERS 4 #define MAX_DIRECTOR_CMD_STRING 128 -#endif//HLTV_H \ No newline at end of file +#endif//HLTV_H diff --git a/common/ivoicetweak.h b/common/ivoicetweak.h index 541a63fa..96879beb 100644 --- a/common/ivoicetweak.h +++ b/common/ivoicetweak.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef IVOICETWEAK_H #define IVOICETWEAK_H @@ -37,4 +37,4 @@ typedef struct IVoiceTweak_s int (*GetSpeakingVolume)( void ); } IVoiceTweak; -#endif//IVOICETWEAK_H \ No newline at end of file +#endif//IVOICETWEAK_H diff --git a/common/lightstyle.h b/common/lightstyle.h index 8b42edac..a12702f4 100644 --- a/common/lightstyle.h +++ b/common/lightstyle.h @@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ - +#pragma once #ifndef LIGHTSTYLE_H #define LIGHTSTYLE_H @@ -26,4 +26,4 @@ typedef struct float time; // local time is gurantee what new style begins from the start, not mid or end of the sequence } lightstyle_t; -#endif//LIGHTSTYLE_H \ No newline at end of file +#endif//LIGHTSTYLE_H diff --git a/common/mathlib.h b/common/mathlib.h index 12fb972f..6bcf76eb 100644 --- a/common/mathlib.h +++ b/common/mathlib.h @@ -13,7 +13,9 @@ * ****/ // mathlib.h - +#pragma once +#ifndef MATHLIB_H +#define MATHLIB_H #include typedef float vec_t; @@ -98,3 +100,4 @@ float anglemod(float a); ) \ : \ BoxOnPlaneSide( (emins), (emaxs), (p))) +#endif // MATHLIB_H diff --git a/common/net_api.h b/common/net_api.h index 00831394..da18fc30 100644 --- a/common/net_api.h +++ b/common/net_api.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef NET_API_H #define NET_API_H @@ -94,4 +94,4 @@ typedef struct net_api_s void (*SetValueForKey)( char *s, const char *key, const char *value, int maxsize ); } net_api_t; -#endif//NET_APIH \ No newline at end of file +#endif // NET_APIH diff --git a/common/netadr.h b/common/netadr.h index dfeea8b0..0d70a22b 100644 --- a/common/netadr.h +++ b/common/netadr.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef NETADR_H #define NETADR_H @@ -34,4 +34,4 @@ typedef struct netadr_s unsigned short port; } netadr_t; -#endif//NETADR_H \ No newline at end of file +#endif//NETADR_H diff --git a/common/particledef.h b/common/particledef.h index 3f2ead66..15c95feb 100644 --- a/common/particledef.h +++ b/common/particledef.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef PARTICLEDEF_H #define PARTICLEDEF_H @@ -51,4 +51,4 @@ typedef struct particle_s unsigned char context; } particle_t; -#endif//PARTICLEDEF_H \ No newline at end of file +#endif//PARTICLEDEF_H diff --git a/common/pmtrace.h b/common/pmtrace.h index 6394de56..d5dd1453 100644 --- a/common/pmtrace.h +++ b/common/pmtrace.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef PM_TRACE_H #define PM_TRACE_H @@ -38,4 +38,4 @@ struct pmtrace_s int hitgroup; }; -#endif//PM_TRACE_H \ No newline at end of file +#endif//PM_TRACE_H diff --git a/common/qfont.h b/common/qfont.h index 06408572..beb36ff9 100644 --- a/common/qfont.h +++ b/common/qfont.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef QFONT_H #define QFONT_H @@ -35,4 +35,4 @@ typedef struct qfont_s byte data[4]; } qfont_t; -#endif//QFONT_H \ No newline at end of file +#endif//QFONT_H diff --git a/common/r_efx.h b/common/r_efx.h index fc27bef7..1a55aa0b 100644 --- a/common/r_efx.h +++ b/common/r_efx.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef R_EFX_H #define R_EFX_H @@ -192,4 +192,4 @@ struct efx_api_s void (*R_FireCustomDecal)( int textureIndex, int entity, int modelIndex, float *position, int flags, float scale ); }; -#endif//R_EFX_H \ No newline at end of file +#endif//R_EFX_H diff --git a/common/r_studioint.h b/common/r_studioint.h index 00384a16..b17e826f 100644 --- a/common/r_studioint.h +++ b/common/r_studioint.h @@ -12,8 +12,7 @@ * without written permission from Valve LLC. * ****/ - - +#pragma once #ifndef R_STUDIOINT_H #define R_STUDIOINT_H @@ -151,4 +150,4 @@ typedef struct sv_blending_interface_s const edict_t *pEdict ); } sv_blending_interface_t; -#endif//R_STUDIOINT_H \ No newline at end of file +#endif//R_STUDIOINT_H diff --git a/common/ref_params.h b/common/ref_params.h index 0458c4f4..61527eca 100644 --- a/common/ref_params.h +++ b/common/ref_params.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef REF_PARAMS_H #define REF_PARAMS_H @@ -87,4 +87,4 @@ typedef struct ref_overview_s float flZoom; } ref_overview_t; -#endif//REF_PARAMS_H \ No newline at end of file +#endif//REF_PARAMS_H diff --git a/common/render_api.h b/common/render_api.h index 7a9fcffe..03973f27 100644 --- a/common/render_api.h +++ b/common/render_api.h @@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ - +#pragma once #ifndef RENDER_API_H #define RENDER_API_H @@ -258,4 +258,4 @@ typedef struct render_interface_s void (*Mod_ProcessUserData)( struct model_s *mod, qboolean create, const byte *buffer ); } render_interface_t; -#endif//RENDER_API_H \ No newline at end of file +#endif//RENDER_API_H diff --git a/common/screenfade.h b/common/screenfade.h index 730f729e..1611f914 100644 --- a/common/screenfade.h +++ b/common/screenfade.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef SCREENFADE_H #define SCREENFADE_H @@ -26,4 +26,4 @@ typedef struct screenfade_s int fadeFlags; // Fading flags } screenfade_t; -#endif//SCREENFADE_H \ No newline at end of file +#endif//SCREENFADE_H diff --git a/common/studio_event.h b/common/studio_event.h index 29ea1f90..cf21e82a 100644 --- a/common/studio_event.h +++ b/common/studio_event.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef STUDIO_EVENT_H #define STUDIO_EVENT_H @@ -24,4 +24,4 @@ typedef struct mstudioevent_s char options[64]; } mstudioevent_t; -#endif//STUDIO_EVENT_H \ No newline at end of file +#endif//STUDIO_EVENT_H diff --git a/common/triangleapi.h b/common/triangleapi.h index f2e9a309..49dc919f 100644 --- a/common/triangleapi.h +++ b/common/triangleapi.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef TRIANGLEAPI_H #define TRIANGLEAPI_H diff --git a/common/usercmd.h b/common/usercmd.h index 96e3c91b..538c60a6 100644 --- a/common/usercmd.h +++ b/common/usercmd.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef USERCMD_H #define USERCMD_H @@ -36,4 +36,4 @@ typedef struct usercmd_s vec3_t impact_position; } usercmd_t; -#endif//USERCMD_H \ No newline at end of file +#endif//USERCMD_H diff --git a/common/wadfile.h b/common/wadfile.h index 38a08032..84ffbb2d 100644 --- a/common/wadfile.h +++ b/common/wadfile.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef WADFILE_H #define WADFILE_H @@ -76,4 +76,4 @@ typedef struct mip_s unsigned int offsets[4]; // four mip maps stored } mip_t; -#endif//WADFILE_H \ No newline at end of file +#endif//WADFILE_H diff --git a/common/weaponinfo.h b/common/weaponinfo.h index ae78c645..b94857b6 100644 --- a/common/weaponinfo.h +++ b/common/weaponinfo.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef WEAPONINFO_H #define WEAPONINFO_H @@ -47,4 +47,4 @@ typedef struct weapon_data_s float fuser4; } weapon_data_t; -#endif//WEAPONINFO_H \ No newline at end of file +#endif//WEAPONINFO_H diff --git a/common/wrect.h b/common/wrect.h index 8dd2ba2f..51e84d88 100644 --- a/common/wrect.h +++ b/common/wrect.h @@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ - +#pragma once #ifndef WRECT_H #define WRECT_H @@ -21,4 +21,4 @@ typedef struct wrect_s int left, right, top, bottom; } wrect_t; -#endif//WRECT_H \ No newline at end of file +#endif//WRECT_H diff --git a/dlls/activity.h b/dlls/activity.h index 5382d70d..90d85a08 100644 --- a/dlls/activity.h +++ b/dlls/activity.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef ACTIVITY_H #define ACTIVITY_H diff --git a/dlls/activitymap.h b/dlls/activitymap.h index 5f77c55a..b5f789f9 100644 --- a/dlls/activitymap.h +++ b/dlls/activitymap.h @@ -12,7 +12,9 @@ * without written permission from Valve LLC. * ****/ - +#pragma once +#ifndef ACTIVITYMAP_H +#define ACTIVITYMAP_H #define _A( a ) { a, #a } activity_map_t activity_map[] = @@ -95,3 +97,4 @@ _A( ACT_FLINCH_LEFTLEG ), _A( ACT_FLINCH_RIGHTLEG ), { 0, NULL } }; +#endif // ACTIVITYMAP_H diff --git a/dlls/animation.h b/dlls/animation.h index 384c1e98..6def910c 100644 --- a/dlls/animation.h +++ b/dlls/animation.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef ANIMATION_H #define ANIMATION_H diff --git a/dlls/basemonster.h b/dlls/basemonster.h index 0d22104f..2234aaf9 100644 --- a/dlls/basemonster.h +++ b/dlls/basemonster.h @@ -12,7 +12,7 @@ * use or distribution of this code by or to any unlicensed person is illegal. * ****/ - +#pragma once #ifndef BASEMONSTER_H #define BASEMONSTER_H diff --git a/dlls/cbase.h b/dlls/cbase.h index 10f7a85f..4cf40abd 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef CBASE_H #define CBASE_H /* diff --git a/dlls/cdll_dll.h b/dlls/cdll_dll.h index c960a6ac..0aafafbd 100644 --- a/dlls/cdll_dll.h +++ b/dlls/cdll_dll.h @@ -16,7 +16,7 @@ // cdll_dll.h // this file is included by both the game-dll and the client-dll, - +#pragma once #ifndef CDLL_DLL_H #define CDLL_DLL_H diff --git a/dlls/client.h b/dlls/client.h index 6728151b..6feaac1a 100644 --- a/dlls/client.h +++ b/dlls/client.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef CLIENT_H #define CLIENT_H diff --git a/dlls/decals.h b/dlls/decals.h index 97f5f29f..5de54421 100644 --- a/dlls/decals.h +++ b/dlls/decals.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef DECALS_H #define DECALS_H diff --git a/dlls/doors.h b/dlls/doors.h index 7e89b497..fe2b5a85 100644 --- a/dlls/doors.h +++ b/dlls/doors.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef DOORS_H #define DOORS_H diff --git a/dlls/effects.cpp b/dlls/effects.cpp index 2e127b2d..bd9959f9 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -379,10 +379,9 @@ public: void BeamUpdateVars( void ); + int m_active; string_t m_iszStartEntity; string_t m_iszEndEntity; - string_t m_iszSpriteName; - int m_active; float m_life; int m_boltWidth; int m_noiseAmplitude; @@ -390,6 +389,7 @@ public: int m_speed; float m_restrike; int m_spriteTexture; + string_t m_iszSpriteName; int m_frameStart; float m_radius; diff --git a/dlls/effects.h b/dlls/effects.h index f4b6b5b2..5dd55209 100644 --- a/dlls/effects.h +++ b/dlls/effects.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef EFFECTS_H #define EFFECTS_H diff --git a/dlls/explode.h b/dlls/explode.h index e1c6cce0..001d93ca 100644 --- a/dlls/explode.h +++ b/dlls/explode.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef EXPLODE_H #define EXPLODE_H @@ -26,4 +27,4 @@ extern DLL_GLOBAL short g_sModelIndexFireball; extern DLL_GLOBAL short g_sModelIndexSmoke; extern void ExplosionCreate( const Vector ¢er, const Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage ); -#endif //EXPLODE_H +#endif // EXPLODE_H diff --git a/dlls/exportdef.h b/dlls/exportdef.h index 995613ff..363d8d12 100644 --- a/dlls/exportdef.h +++ b/dlls/exportdef.h @@ -1,3 +1,4 @@ +#pragma once #ifndef EXPORTDEF_H #define EXPORTDEF_H #if defined _WIN32 || defined __CYGWIN__ diff --git a/dlls/extdll.h b/dlls/extdll.h index 812ce40f..d6ea4888 100644 --- a/dlls/extdll.h +++ b/dlls/extdll.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef EXTDLL_H #define EXTDLL_H diff --git a/dlls/flyingmonster.h b/dlls/flyingmonster.h index 4dd87fb4..31ff4e33 100644 --- a/dlls/flyingmonster.h +++ b/dlls/flyingmonster.h @@ -13,7 +13,7 @@ * ****/ // Base class for flying monsters. This overrides the movement test & execution code from CBaseMonster - +#pragma once #ifndef FLYINGMONSTER_H #define FLYINGMONSTER_H diff --git a/dlls/func_break.h b/dlls/func_break.h index b4ff1fc1..89c9f54e 100644 --- a/dlls/func_break.h +++ b/dlls/func_break.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef FUNC_BREAK_H #define FUNC_BREAK_H @@ -82,9 +83,9 @@ public: Materials m_Material; Explosions m_Explosion; - string_t m_iszGibModel; - string_t m_iszSpawnObject; int m_idShard; float m_angle; + string_t m_iszGibModel; + string_t m_iszSpawnObject; }; #endif // FUNC_BREAK_H diff --git a/dlls/func_tank.cpp b/dlls/func_tank.cpp index 013948eb..a3dba841 100644 --- a/dlls/func_tank.cpp +++ b/dlls/func_tank.cpp @@ -97,9 +97,6 @@ public: protected: CBasePlayer* m_pController; - string_t m_iszSpriteSmoke; - string_t m_iszSpriteFlash; - string_t m_iszMaster; // Master entity (game_team_master or multisource) float m_flNextAttack; Vector m_vecControllerUsePos; @@ -123,11 +120,14 @@ protected: Vector m_barrelPos; // Length of the freakin barrel float m_spriteScale; // Scale of any sprites we shoot + string_t m_iszSpriteSmoke; + string_t m_iszSpriteFlash; TANKBULLET m_bulletType; // Bullet type int m_iBulletDamage; // 0 means use Bullet type's default damage Vector m_sightOrigin; // Last sight of target int m_spread; // firing spread + string_t m_iszMaster; // Master entity (game_team_master or multisource) }; TYPEDESCRIPTION CFuncTank::m_SaveData[] = diff --git a/dlls/game.h b/dlls/game.h index a6d0cd1c..0dc5ba87 100644 --- a/dlls/game.h +++ b/dlls/game.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef GAME_H #define GAME_H diff --git a/dlls/gamerules.h b/dlls/gamerules.h index 71036151..04c6eea5 100644 --- a/dlls/gamerules.h +++ b/dlls/gamerules.h @@ -15,6 +15,7 @@ //========================================================= // GameRules //========================================================= +#pragma once #ifndef GAMERULES_H #define GAMERULES_H //#include "weapons.h" diff --git a/dlls/hornet.h b/dlls/hornet.h index dc78fc40..f0f0d366 100644 --- a/dlls/hornet.h +++ b/dlls/hornet.h @@ -15,7 +15,9 @@ //========================================================= // Hornets //========================================================= - +#pragma once +#ifndef HORNET_H +#define HORNET_H //========================================================= // Hornet Defines //========================================================= @@ -55,3 +57,4 @@ public: int m_iHornetType; float m_flFlySpeed; }; +#endif // HORNET_H diff --git a/dlls/items.h b/dlls/items.h index 2c31f801..060678c8 100644 --- a/dlls/items.h +++ b/dlls/items.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef ITEMS_H #define ITEMS_H diff --git a/dlls/lights.cpp b/dlls/lights.cpp index 8a4f8de8..1c39266b 100644 --- a/dlls/lights.cpp +++ b/dlls/lights.cpp @@ -37,8 +37,8 @@ public: static TYPEDESCRIPTION m_SaveData[]; private: - string_t m_iszPattern; int m_iStyle; + string_t m_iszPattern; }; LINK_ENTITY_TO_CLASS( light, CLight ) diff --git a/dlls/monsters.h b/dlls/monsters.h index 6f2df294..4aeca3a9 100644 --- a/dlls/monsters.h +++ b/dlls/monsters.h @@ -12,6 +12,7 @@ * use or distribution of this code by or to any unlicensed person is illegal. * ****/ +#pragma once #ifndef MONSTERS_H #include "skill.h" #define MONSTERS_H diff --git a/dlls/nodes.h b/dlls/nodes.h index 49036a39..52b715e5 100644 --- a/dlls/nodes.h +++ b/dlls/nodes.h @@ -15,6 +15,7 @@ //========================================================= // nodes.h //========================================================= +#pragma once #ifndef NODES_H #define NODES_H //========================================================= diff --git a/dlls/physcallback.h b/dlls/physcallback.h index 1db276e0..fd68936c 100644 --- a/dlls/physcallback.h +++ b/dlls/physcallback.h @@ -12,9 +12,9 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef PHYSCALLBACK_H #define PHYSCALLBACK_H -#pragma once #include "physint.h" diff --git a/dlls/player.h b/dlls/player.h index fecaf3c9..6fc06dbb 100644 --- a/dlls/player.h +++ b/dlls/player.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef PLAYER_H #define PLAYER_H diff --git a/dlls/saverestore.h b/dlls/saverestore.h index 4295871d..81f9f131 100644 --- a/dlls/saverestore.h +++ b/dlls/saverestore.h @@ -13,6 +13,7 @@ * ****/ // Implementation in UTIL.CPP +#pragma once #ifndef SAVERESTORE_H #define SAVERESTORE_H diff --git a/dlls/schedule.h b/dlls/schedule.h index 0c4fb1ce..6414ff15 100644 --- a/dlls/schedule.h +++ b/dlls/schedule.h @@ -15,7 +15,7 @@ //========================================================= // Scheduling //========================================================= - +#pragma once #ifndef SCHEDULE_H #define SCHEDULE_H diff --git a/dlls/scripted.cpp b/dlls/scripted.cpp index 92b9aa6a..41638b39 100644 --- a/dlls/scripted.cpp +++ b/dlls/scripted.cpp @@ -909,13 +909,13 @@ public: private: string_t m_iszSentence; // string index for idle animation string_t m_iszEntity; // entity that is wanted for this sentence - string_t m_iszListener; // name of entity to look at while talking float m_flRadius; // range to search float m_flDuration; // How long the sentence lasts float m_flRepeat; // repeat rate float m_flAttenuation; float m_flVolume; BOOL m_active; + string_t m_iszListener; // name of entity to look at while talking }; #define SF_SENTENCE_ONCE 0x0001 diff --git a/dlls/scripted.h b/dlls/scripted.h index 6cf8cfa1..59b696f7 100644 --- a/dlls/scripted.h +++ b/dlls/scripted.h @@ -12,6 +12,7 @@ * use or distribution of this code by or to any unlicensed person is illegal. * ****/ +#pragma once #ifndef SCRIPTED_H #define SCRIPTED_H diff --git a/dlls/scriptevent.h b/dlls/scriptevent.h index 714ac99c..18436a26 100644 --- a/dlls/scriptevent.h +++ b/dlls/scriptevent.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef SCRIPTEVENT_H #define SCRIPTEVENT_H @@ -26,4 +27,4 @@ #define SCRIPT_EVENT_SOUND_VOICE 1008 // Play named wave file (on CHAN_VOICE) #define SCRIPT_EVENT_SENTENCE_RND1 1009 // Play sentence group 25% of the time #define SCRIPT_EVENT_NOT_DEAD 1010 // Bring back to life (for life/death sequences) -#endif //SCRIPTEVENT_H +#endif // SCRIPTEVENT_H diff --git a/dlls/skill.h b/dlls/skill.h index aa338362..5244c923 100644 --- a/dlls/skill.h +++ b/dlls/skill.h @@ -15,6 +15,7 @@ //========================================================= // skill.h - skill level concerns //========================================================= +#pragma once #ifndef SKILL_H #define SKILL_H @@ -23,7 +24,7 @@ struct skilldata_t int iSkillLevel; // game skill level // Monster Health & Damage - float agruntHealth; + float agruntHealth; float agruntDmgPunch; float apacheHealth; diff --git a/dlls/soundent.h b/dlls/soundent.h index 6c39a6c0..88def506 100644 --- a/dlls/soundent.h +++ b/dlls/soundent.h @@ -17,6 +17,9 @@ // spawns, and handles the world's active and free sound // lists. //========================================================= +#pragma once +#ifndef SOUNDENT_H +#define SOUNDENT_H #define MAX_WORLD_SOUNDS 64 // maximum number of sounds handled by the world at one time. @@ -91,3 +94,4 @@ public: private: CSound m_SoundPool[ MAX_WORLD_SOUNDS ]; }; +#endif // SOUNDENT_H diff --git a/dlls/spectator.h b/dlls/spectator.h index 00567fc6..c4e895c0 100644 --- a/dlls/spectator.h +++ b/dlls/spectator.h @@ -13,6 +13,7 @@ * ****/ // Spectator.h +#pragma once #ifndef SPECTATOR_H #define SPECTATOR_H diff --git a/dlls/squad.h b/dlls/squad.h index c29a7199..f8f20aa0 100644 --- a/dlls/squad.h +++ b/dlls/squad.h @@ -7,6 +7,7 @@ //========================================================= // squad.h //========================================================= +#pragma once #ifndef SQUAD_H #define SQUAD_H diff --git a/dlls/squadmonster.h b/dlls/squadmonster.h index 132d4177..e2c8a5b9 100644 --- a/dlls/squadmonster.h +++ b/dlls/squadmonster.h @@ -16,6 +16,7 @@ // CSquadMonster - all the extra data for monsters that // form squads. //========================================================= +#pragma once #ifndef SQUADMONSTER_H #define SQUADMONSTER_H diff --git a/dlls/talkmonster.h b/dlls/talkmonster.h index 084861bc..36ac21a6 100644 --- a/dlls/talkmonster.h +++ b/dlls/talkmonster.h @@ -12,6 +12,7 @@ * use or distribution of this code by or to any unlicensed person is illegal. * ****/ +#pragma once #ifndef TALKMONSTER_H #define TALKMONSTER_H diff --git a/dlls/teamplay_gamerules.h b/dlls/teamplay_gamerules.h index 06823ca6..12ed038f 100644 --- a/dlls/teamplay_gamerules.h +++ b/dlls/teamplay_gamerules.h @@ -15,6 +15,9 @@ // // teamplay_gamerules.h // +#pragma once +#ifndef TEAMPLAY_GAMERULES_H +#define TEAMPLAY_GAMERULES_H #define MAX_TEAMNAME_LENGTH 16 #define MAX_TEAMS 32 @@ -55,3 +58,4 @@ private: BOOL m_teamLimit; // This means the server set only some teams as valid char m_szTeamList[TEAMPLAY_TEAMLISTLENGTH]; }; +#endif // TEAMPLAY_GAMERULES_H diff --git a/dlls/trains.h b/dlls/trains.h index e8003b3e..f740e2ea 100644 --- a/dlls/trains.h +++ b/dlls/trains.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef TRAINS_H #define TRAINS_H diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index 7d7f255c..6d8fef04 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -267,11 +267,11 @@ public: static TYPEDESCRIPTION m_SaveData[]; - string_t m_iTargetName[MAX_MULTI_TARGETS];// list if indexes into global string array - float m_flTargetDelay[MAX_MULTI_TARGETS];// delay (in seconds) from time of manager fire to target fire int m_cTargets; // the total number of targets in this manager's fire list. int m_index; // Current target float m_startTime;// Time we started firing + string_t m_iTargetName[MAX_MULTI_TARGETS];// list if indexes into global string array + float m_flTargetDelay[MAX_MULTI_TARGETS];// delay (in seconds) from time of manager fire to target fire private: inline BOOL IsClone( void ) { return ( pev->spawnflags & SF_MULTIMAN_CLONE ) ? TRUE : FALSE; } inline BOOL ShouldClone( void ) @@ -1321,9 +1321,9 @@ public: static TYPEDESCRIPTION m_SaveData[]; - string_t m_changeTarget; char m_szMapName[cchMapNameMost]; // trigger_changelevel only: next map char m_szLandmarkName[cchMapNameMost]; // trigger_changelevel only: landmark on next map + string_t m_changeTarget; float m_changeTargetDelay; }; diff --git a/dlls/util.h b/dlls/util.h index 8f56cd76..7f9dea70 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef UTIL_H #define UTIL_H // diff --git a/dlls/vector.h b/dlls/vector.h index 265a9b00..48c707b4 100644 --- a/dlls/vector.h +++ b/dlls/vector.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef VECTOR_H #define VECTOR_H diff --git a/dlls/weapons.h b/dlls/weapons.h index 0cfa2031..312f5531 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef WEAPONS_H #define WEAPONS_H diff --git a/engine/cdll_exp.h b/engine/cdll_exp.h index bf43654c..e4c1f5d8 100644 --- a/engine/cdll_exp.h +++ b/engine/cdll_exp.h @@ -12,6 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ +#pragma once #ifndef CDLL_EXP_H #define CDLL_EXP_H @@ -66,4 +67,4 @@ typedef struct cldll_func_s void (*pfnClipMoveToEntity)( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr ); } cldll_func_t; -#endif//CDLL_EXP_H \ No newline at end of file +#endif//CDLL_EXP_H diff --git a/engine/cdll_int.h b/engine/cdll_int.h index 20af4b55..abfc43bd 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -18,7 +18,7 @@ // 4-23-98 // JOHN: client dll interface declarations // - +#pragma once #ifndef CDLL_INT_H #define CDLL_INT_H diff --git a/engine/custom.h b/engine/custom.h index 30ee8d53..02aa2089 100644 --- a/engine/custom.h +++ b/engine/custom.h @@ -12,11 +12,10 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef CUSTOM_H #define CUSTOM_H -#pragma once - #include "const.h" ///////////////// diff --git a/engine/customentity.h b/engine/customentity.h index 63e672f8..f524ae79 100644 --- a/engine/customentity.h +++ b/engine/customentity.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef CUSTOMENTITY_H #define CUSTOMENTITY_H diff --git a/engine/edict.h b/engine/edict.h index 3994c705..8584a0d9 100644 --- a/engine/edict.h +++ b/engine/edict.h @@ -12,12 +12,10 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef EDICT_H #define EDICT_H -#pragma once - #define MAX_ENT_LEAFS 48 #include "progdefs.h" diff --git a/engine/eiface.h b/engine/eiface.h index 6fa51c12..f6cf2f51 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef EIFACE_H #define EIFACE_H diff --git a/engine/keydefs.h b/engine/keydefs.h index ea22139f..5593d75a 100644 --- a/engine/keydefs.h +++ b/engine/keydefs.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef KEYDEFS_H #define KEYDEFS_H @@ -130,4 +130,4 @@ #define K_MOUSE4 244 #define K_MOUSE5 245 -#endif//KEYDEFS_H \ No newline at end of file +#endif//KEYDEFS_H diff --git a/engine/menu_int.h b/engine/menu_int.h index 69c10ce4..d907bd87 100644 --- a/engine/menu_int.h +++ b/engine/menu_int.h @@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ - +#pragma once #ifndef MENU_INT_H #define MENU_INT_H diff --git a/engine/physint.h b/engine/physint.h index af923a00..2b4ac8f7 100644 --- a/engine/physint.h +++ b/engine/physint.h @@ -12,7 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ - +#pragma once #ifndef PHYSINT_H #define PHYSINT_H @@ -111,4 +111,4 @@ typedef struct physics_interface_s int (*pfnRestoreDecal)( struct decallist_s *entry, edict_t *pEdict, qboolean adjacent ); } physics_interface_t; -#endif//PHYSINT_H \ No newline at end of file +#endif//PHYSINT_H diff --git a/engine/progdefs.h b/engine/progdefs.h index 56d904b1..31cfb3cb 100644 --- a/engine/progdefs.h +++ b/engine/progdefs.h @@ -12,11 +12,10 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef PROGDEFS_H #define PROGDEFS_H -#pragma once - typedef struct { float time; diff --git a/engine/shake.h b/engine/shake.h index b2e88a33..a3e49324 100644 --- a/engine/shake.h +++ b/engine/shake.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef SHAKE_H #define SHAKE_H diff --git a/engine/sprite.h b/engine/sprite.h index afc81a4e..4368c1ac 100644 --- a/engine/sprite.h +++ b/engine/sprite.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef SPRITE_H #define SPRITE_H @@ -99,4 +99,4 @@ typedef struct frametype_t type; } dframetype_t; -#endif//SPRITE_H \ No newline at end of file +#endif//SPRITE_H diff --git a/engine/studio.h b/engine/studio.h index 00e7ad27..88254c96 100644 --- a/engine/studio.h +++ b/engine/studio.h @@ -12,7 +12,7 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef STUDIO_H #define STUDIO_H diff --git a/pm_shared/pm_debug.h b/pm_shared/pm_debug.h index 417c3478..6c91d62e 100644 --- a/pm_shared/pm_debug.h +++ b/pm_shared/pm_debug.h @@ -12,11 +12,10 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef PM_DEBUG_H #define PM_DEBUG_H -#pragma once - void PM_ViewEntity( void ); void PM_DrawBBox( vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life ); void PM_ParticleLine( vec3_t start, vec3_t end, int pcolor, float life, float vert ); diff --git a/pm_shared/pm_defs.h b/pm_shared/pm_defs.h index eddb17b6..82480806 100644 --- a/pm_shared/pm_defs.h +++ b/pm_shared/pm_defs.h @@ -12,11 +12,10 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef PM_DEFS_H #define PM_DEFS_H -#pragma once - #define MAX_PHYSENTS 600 // Must have room for all entities in the world. #define MAX_MOVEENTS 64 #define MAX_CLIP_PLANES 5 diff --git a/pm_shared/pm_info.h b/pm_shared/pm_info.h index d75b67fc..9a971d53 100644 --- a/pm_shared/pm_info.h +++ b/pm_shared/pm_info.h @@ -12,10 +12,9 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef PM_INFO_H #define PM_INFO_H -#pragma once - #define MAX_PHYSINFO_STRING 256 #endif//PM_INFO_H diff --git a/pm_shared/pm_materials.h b/pm_shared/pm_materials.h index e625b4fc..9bc71b72 100644 --- a/pm_shared/pm_materials.h +++ b/pm_shared/pm_materials.h @@ -12,6 +12,7 @@ * without written permission from Valve LLC. * ****/ +#pragma once #ifndef PM_MATERIALS_H #define PM_MATERIALS_H diff --git a/pm_shared/pm_movevars.h b/pm_shared/pm_movevars.h index 35fa5b4f..61eb06fd 100644 --- a/pm_shared/pm_movevars.h +++ b/pm_shared/pm_movevars.h @@ -6,6 +6,7 @@ //============================================================================= // pm_movevars.h +#pragma once #if !defined( PM_MOVEVARSH ) #define PM_MOVEVARSH diff --git a/pm_shared/pm_shared.h b/pm_shared/pm_shared.h index 2fb947a2..c315353b 100644 --- a/pm_shared/pm_shared.h +++ b/pm_shared/pm_shared.h @@ -12,12 +12,10 @@ * without written permission from Valve LLC. * ****/ - +#pragma once #ifndef PM_SHARED_H #define PM_SHARED_H -#pragma once - void PM_Init( struct playermove_s *ppmove ); void PM_Move( struct playermove_s *ppmove, int server ); char PM_FindTextureType( char *name ); From bf429f0709d5045a8cf2880b3b035fb0ab0b41e7 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sat, 16 Dec 2017 04:56:23 +0300 Subject: [PATCH 135/211] Fix item soda precache --- dlls/effects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/effects.cpp b/dlls/effects.cpp index bd9959f9..bd12f8aa 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -2182,7 +2182,7 @@ public: void CItemSoda::Precache( void ) { PRECACHE_MODEL( "models/can.mdl" ); - PRECACHE_SOUND( "weapons/g_bounce.wav" ); + PRECACHE_SOUND( "weapons/g_bounce3.wav" ); } LINK_ENTITY_TO_CLASS( item_sodacan, CItemSoda ) From a2f0ecf7419e58b7bd3a15257ecf954786e18128 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Mon, 18 Dec 2017 02:44:42 +0500 Subject: [PATCH 136/211] Fix linking with libdl on some environments. --- cl_dll/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index e3ac075a..aa1e94f8 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -28,9 +28,6 @@ set (CLDLL_LIBRARY client) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w") if (GOLDSOURCE_SUPPORT) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT") - if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ldl") - endif() endif() set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") @@ -109,6 +106,9 @@ if(USE_VOICEMGR) endif() add_library (${CLDLL_LIBRARY} SHARED ${CLDLL_SOURCES}) +if (GOLDSOURCE_SUPPORT) + target_link_libraries( ${CLDLL_LIBRARY} ${CMAKE_DL_LIBS} ) +endif() set_target_properties (${CLDLL_SHARED} PROPERTIES POSITION_INDEPENDENT_CODE 1) From c128c69ceb2a96730ffe487bef234c4e59f3cac3 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 19 Dec 2017 00:27:56 +0300 Subject: [PATCH 137/211] Add install() for CMake. --- CMakeLists.txt | 4 ++++ cl_dll/CMakeLists.txt | 13 ++++++++++++- dlls/CMakeLists.txt | 13 ++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7719bac6..0d754eb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,10 @@ option(USE_VOICEMGR "Enable VOICE MANAGER." OFF) option(BUILD_CLIENT "Build client dll" ON) option(BUILD_SERVER "Build server dll" ON) option(GOLDSOURCE_SUPPORT "Build goldsource compatible client library" OFF) +set(GAMEDIR "valve" CACHE STRING "Gamedir path") +set(SERVER_INSTALL_DIR "dlls" CACHE STRING "Where put server dll") +set(CLIENT_INSTALL_DIR "cl_dlls" CACHE STRING "Where put client dll") +set(SERVER_LIBRARY_NAME "hl" CACHE STRING "Library name for Linux/MacOS/Windows") #----------------- # MAIN BUILD CODE \ diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index aa1e94f8..2d247950 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -110,6 +110,17 @@ if (GOLDSOURCE_SUPPORT) target_link_libraries( ${CLDLL_LIBRARY} ${CMAKE_DL_LIBS} ) endif() -set_target_properties (${CLDLL_SHARED} PROPERTIES +set_target_properties (${CLDLL_LIBRARY} PROPERTIES POSITION_INDEPENDENT_CODE 1) +if(APPLE OR WIN32 OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set_target_properties(${CLDLL_LIBRARY} PROPERTIES + OUTPUT_NAME "client" + PREFIX "") +endif() + +install( TARGETS ${CLDLL_LIBRARY} + DESTINATION "${GAMEDIR}/${CLIENT_INSTALL_DIR}/" + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE ) diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index 4e56ab44..480b61d1 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -145,6 +145,17 @@ endif() add_library (${SVDLL_LIBRARY} SHARED ${SVDLL_SOURCES}) -set_target_properties (${SVDLL_SHARED} PROPERTIES +set_target_properties (${SVDLL_LIBRARY} PROPERTIES POSITION_INDEPENDENT_CODE 1) +if(APPLE OR WIN32 OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set_target_properties(${SVDLL_LIBRARY} PROPERTIES + OUTPUT_NAME ${SERVER_LIBRARY_NAME} + PREFIX "") +endif() + +install( TARGETS ${SVDLL_LIBRARY} + DESTINATION "${GAMEDIR}/${SERVER_INSTALL_DIR}/" + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) From 7981bad606f0a251b3904405539b667c06c676f5 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 19 Dec 2017 00:28:34 +0300 Subject: [PATCH 138/211] Fix weapon selection being broken at the start of demo(or manual fullupdate call) --- dlls/player.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dlls/player.cpp b/dlls/player.cpp index d0a1f763..52f5f546 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -3327,6 +3327,10 @@ void CBasePlayer::ForceClientDllUpdate( void ) m_fWeapon = FALSE; // Force weapon send m_fKnownItem = FALSE; // Force weaponinit messages. m_fInitHUD = TRUE; // Force HUD gmsgResetHUD message + m_bSentBhopcap = true; // a1ba: Update bhopcap state + memset( m_rgAmmoLast, 0, sizeof( m_rgAmmoLast )); // a1ba: Force update AmmoX + + // Now force all the necessary messages // to be sent. From 113135f7b9dd9d0dcd54f2e6724f016148faa1d8 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Mon, 18 Dec 2017 23:58:30 +0300 Subject: [PATCH 139/211] Ignore dlls, pdb, some cmake generated files and orig files produced by some diff programs --- .gitignore | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 26362f60..a0bc5604 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,14 @@ *.a *.framework *.exe -build/ \ No newline at end of file +*.dll +*.pdb +build/ +CMakeLists.txt.user +cmake_install.cmake +*.orig +*.cbp +*.dsw +*.vsxproj +*.vsproj +*.sln From 6be68c49f334b63055ffe09da94cd5295ae4bc15 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 20 Dec 2017 04:35:54 +0300 Subject: [PATCH 140/211] Remove redundant files of original xash3d hlsdk --- backup.bat | 31 ------------------------- backup.lst | 36 ----------------------------- debug.bat | 42 --------------------------------- make_sdk.bat | 62 ------------------------------------------------- release.bat | 42 --------------------------------- xash.dsw | 65 ---------------------------------------------------- xash_sdk.dsw | 65 ---------------------------------------------------- xash_sdk.lst | 22 ------------------ 8 files changed, 365 deletions(-) delete mode 100644 backup.bat delete mode 100644 backup.lst delete mode 100644 debug.bat delete mode 100644 make_sdk.bat delete mode 100644 release.bat delete mode 100644 xash.dsw delete mode 100644 xash_sdk.dsw delete mode 100644 xash_sdk.lst diff --git a/backup.bat b/backup.bat deleted file mode 100644 index 7e780aa8..00000000 --- a/backup.bat +++ /dev/null @@ -1,31 +0,0 @@ -@echo off -color 4F -echo XashXT Group 2006 (C) -echo Prepare source for backup -echo. - -if exist backup.log del /f /q backup.log -if not exist D:\!backup/ mkdir D:\!backup\ -echo Prepare OK! -echo Please wait: backup in progress -C:\Progra~1\WinRar\rar a -agMMMYYYY-DD D:\!backup\.rar -dh -m5 @backup.lst >>backup.log -if errorlevel 1 goto error -if errorlevel 0 goto ok -:ok -cls -echo Source was sucessfully backuped -echo and stored in folder "backup" -echo Press any key for exit. :-) -if exist backup.log del /f /q backup.log -exit -:error -echo ****************************** -echo ***********Error!************* -echo ****************************** -echo **See backup.log for details** -echo ****************************** -echo ****************************** -echo. -echo press any key for exit :-( -pause>nul -exit diff --git a/backup.lst b/backup.lst deleted file mode 100644 index 628de079..00000000 --- a/backup.lst +++ /dev/null @@ -1,36 +0,0 @@ -//======================================================================= -// Copyright XashXT Group 2007 © -// list with backup directories -//======================================================================= - -// global stuff -xash.dsw -debug.bat -backup.lst -backup.bat -release.bat -change.log -make_sdk.bat -xash_sdk.lst - -cl_dll\ -cl_dll\hl\ -common\ -dlls\ -game_shared\ -game_launch\ -engine\ -engine\client\ -engine\client\vgui\ -engine\server\ -engine\common\ -engine\common\imagelib\ -engine\common\soundlib\ -pm_shared\ -mainui\ -mainui\legacy -utils\ -utils\makefont\ -utils\vgui\ -utils\vgui\include\ -utils\vgui\lib\win32_vc6\ \ No newline at end of file diff --git a/debug.bat b/debug.bat deleted file mode 100644 index eb702325..00000000 --- a/debug.bat +++ /dev/null @@ -1,42 +0,0 @@ -@echo off - -set MSDEV=BuildConsole -set CONFIG=/ShowTime /ShowAgent /nologo /cfg= -set MSDEV=msdev -set CONFIG=/make -set build_type=debug -set BUILD_ERROR= -call vcvars32 - -%MSDEV% engine/engine.dsp %CONFIG%"engine - Win32 Debug" %build_target% -if errorlevel 1 set BUILD_ERROR=1 - -%MSDEV% mainui/mainui.dsp %CONFIG%"mainui - Win32 Debug" %build_target% -if errorlevel 1 set BUILD_ERROR=1 - -if "%BUILD_ERROR%"=="" goto build_ok - -echo ********************* -echo ********************* -echo *** Build Errors! *** -echo ********************* -echo ********************* -echo press any key to exit -echo ********************* -pause>nul -goto done - - -@rem -@rem Successful build -@rem -:build_ok - -rem //delete log files -if exist engine\engine.plg del /f /q engine\engine.plg -if exist mainui\mainui.plg del /f /q mainui\mainui.plg - -echo -echo Build succeeded! -echo -:done \ No newline at end of file diff --git a/make_sdk.bat b/make_sdk.bat deleted file mode 100644 index 96602839..00000000 --- a/make_sdk.bat +++ /dev/null @@ -1,62 +0,0 @@ -@echo off -color 5A -echo XashXT Group 2010 (C) -echo Create Xash3D SDK -echo. - -if not exist D:\Xash3D\src_main\xash_sdk/ mkdir D:\Xash3D\src_main\xash_sdk\ -if not exist D:\Xash3D\src_main\xash_sdk\engine/ mkdir D:\Xash3D\src_main\xash_sdk\engine\ -if not exist D:\Xash3D\src_main\xash_sdk\common/ mkdir D:\Xash3D\src_main\xash_sdk\common\ -if not exist D:\Xash3D\src_main\xash_sdk\mainui/ mkdir D:\Xash3D\src_main\xash_sdk\mainui\ -if not exist D:\Xash3D\src_main\xash_sdk\mainui\legacy/ mkdir D:\Xash3D\src_main\xash_sdk\mainui\legacy -if not exist D:\Xash3D\src_main\xash_sdk\utils/ mkdir D:\Xash3D\src_main\xash_sdk\utils\ -if not exist D:\Xash3D\src_main\xash_sdk\utils\makefont/ mkdir D:\Xash3D\src_main\xash_sdk\utils\makefont -if not exist D:\Xash3D\src_main\xash_sdk\utils\vgui/ mkdir D:\Xash3D\src_main\xash_sdk\utils\vgui -if not exist D:\Xash3D\src_main\xash_sdk\utils\vgui\include/ mkdir D:\Xash3D\src_main\xash_sdk\utils\vgui\include -if not exist D:\Xash3D\src_main\xash_sdk\utils\vgui\lib/ mkdir D:\Xash3D\src_main\xash_sdk\utils\vgui\lib -if not exist D:\Xash3D\src_main\xash_sdk\utils\vgui\lib\win32_vc6/ mkdir D:\Xash3D\src_main\xash_sdk\utils\vgui\lib\win32_vc6 -if not exist D:\Xash3D\src_main\xash_sdk\game_launch/ mkdir D:\Xash3D\src_main\xash_sdk\game_launch\ -if not exist D:\Xash3D\src_main\xash_sdk\cl_dll/ mkdir D:\Xash3D\src_main\xash_sdk\cl_dll\ -if not exist D:\Xash3D\src_main\xash_sdkcl_dll\hl/ mkdir D:\Xash3D\src_main\xash_sdk\cl_dll\hl\ -if not exist D:\Xash3D\src_main\xash_sdk\dlls/ mkdir D:\Xash3D\src_main\xash_sdk\dlls\ -if not exist D:\Xash3D\src_main\xash_sdk\dlls\wpn_shared/ mkdir D:\Xash3D\src_main\xash_sdk\dlls\wpn_shared\ -if not exist D:\Xash3D\src_main\xash_sdk\game_shared/ mkdir D:\Xash3D\src_main\xash_sdk\game_shared\ -if not exist D:\Xash3D\src_main\xash_sdk\pm_shared/ mkdir D:\Xash3D\src_main\xash_sdk\pm_shared\ -@copy /Y engine\*.h xash_sdk\engine\*.h -@copy /Y game_launch\*.* xash_sdk\game_launch\*.* -@copy /Y mainui\*.* xash_sdk\mainui\*.* -@copy /Y mainui\legacy\*.* xash_sdk\mainui\legacy\*.* -@copy /Y common\*.* xash_sdk\common\*.* -@copy /Y cl_dll\*.* xash_sdk\cl_dll\*.* -@copy /Y cl_dll\hl\*.* xash_sdk\cl_dll\hl\*.* -@copy /Y dlls\*.* xash_sdk\dlls\*.* -@copy /Y dlls\wpn_shared\*.* xash_sdk\dlls\wpn_shared\*.* -@copy /Y utils\makefont\*.* xash_sdk\utils\makefont\*.* -@copy /Y utils\vgui\include\*.* xash_sdk\utils\vgui\include\*.* -@copy /Y utils\vgui\lib\win32_vc6\*.* xash_sdk\utils\vgui\lib\win32_vc6\*.* -@copy /Y game_shared\*.* xash_sdk\game_shared\*.* -@copy /Y pm_shared\*.* xash_sdk\pm_shared\*.* -@copy /Y xash_sdk.dsw xash_sdk\xash_sdk.dsw -echo Prepare OK! -echo Please wait: creating SDK in progress -C:\Progra~1\WinRar\rar a xash_sdk -dh -k -r -s -df -m5 @xash_sdk.lst >>makesdk.log -if errorlevel 1 goto error -if errorlevel 0 goto ok -:ok -cls -echo SDK was sucessfully created -echo and stored in RAR-chive "xash_sdk" -echo Press any key for exit. :-) -if exist makesdk.log del /f /q makesdk.log -exit -:error -echo ****************************** -echo ***********Error!************* -echo ****************************** -echo *See makesdk.log for details** -echo ****************************** -echo ****************************** -echo. -echo press any key for exit :-( -pause>nul -exit \ No newline at end of file diff --git a/release.bat b/release.bat deleted file mode 100644 index dae2d16c..00000000 --- a/release.bat +++ /dev/null @@ -1,42 +0,0 @@ -@echo off - -set MSDEV=BuildConsole -set CONFIG=/ShowTime /ShowAgent /nologo /cfg= -set MSDEV=msdev -set CONFIG=/make -set build_type=release -set BUILD_ERROR= -call vcvars32 - -%MSDEV% engine/engine.dsp %CONFIG%"engine - Win32 Release" %build_target% -if errorlevel 1 set BUILD_ERROR=1 - -%MSDEV% mainui/mainui.dsp %CONFIG%"mainui - Win32 Release" %build_target% -if errorlevel 1 set BUILD_ERROR=1 - -if "%BUILD_ERROR%"=="" goto build_ok - -echo ********************* -echo ********************* -echo *** Build Errors! *** -echo ********************* -echo ********************* -echo press any key to exit -echo ********************* -pause>nul -goto done - - -@rem -@rem Successful build -@rem -:build_ok - -rem //delete log files -if exist engine\engine.plg del /f /q engine\engine.plg -if exist mainui\mainui.plg del /f /q mainui\mainui.plg - -echo -echo Build succeeded! -echo -:done \ No newline at end of file diff --git a/xash.dsw b/xash.dsw deleted file mode 100644 index 3be1a44d..00000000 --- a/xash.dsw +++ /dev/null @@ -1,65 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "hl"=".\dlls\hl.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "client"=".\cl_dll\cl_dll.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "mainui"=".\mainui\mainui.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "engine"=".\engine\engine.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/xash_sdk.dsw b/xash_sdk.dsw deleted file mode 100644 index ad911ba0..00000000 --- a/xash_sdk.dsw +++ /dev/null @@ -1,65 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "hl"=".\dlls\hl.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "client"=".\cl_dll\cl_dll.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "mainui"=".\mainui\mainui.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "game"=".\game_launch\game.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/xash_sdk.lst b/xash_sdk.lst deleted file mode 100644 index a211c3b4..00000000 --- a/xash_sdk.lst +++ /dev/null @@ -1,22 +0,0 @@ -//======================================================================= -// Copyright XashXT Group 2011 © -// list with SDK directories -//======================================================================= - -// global stuff -xash_sdk\xash_sdk.dsw -xash_sdk\cl_dll\ -xash_sdk\cl_dll\hl\ -xash_sdk\common\ -xash_sdk\dlls\ -xash_sdk\game_shared\ -xash_sdk\game_launch\ -xash_sdk\engine\ -xash_sdk\pm_shared\ -xash_sdk\mainui\ -xash_dsk\mainui\legacy -xash_sdk\utils\ -xash_sdk\makefont\ -xash_sdk\utils\vgui\ -xash_sdk\utils\vgui\include\ -xash_sdk\utils\vgui\lib\win32_vc6\ \ No newline at end of file From b66ceab4e586d762408b8e81f88455ec66e00401 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sat, 23 Dec 2017 14:02:59 +0500 Subject: [PATCH 141/211] Fix scoreboard position. --- cl_dll/scoreboard.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index 3adbaab6..908d00f3 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -92,17 +92,17 @@ We have a minimum width of 1-320 - we could have the field widths scale with it? // X positions // relative to the side of the scoreboard -#define NAME_RANGE_MIN -100 -#define NAME_RANGE_MAX 145 -#define KILLS_RANGE_MIN 130 -#define KILLS_RANGE_MAX 170 -#define DIVIDER_POS 180 -#define DEATHS_RANGE_MIN 185 -#define DEATHS_RANGE_MAX 210 -#define PING_RANGE_MIN 245 -#define PING_RANGE_MAX 295 -#define PL_RANGE_MIN 315 -#define PL_RANGE_MAX 375 +#define NAME_RANGE_MIN -65 +#define NAME_RANGE_MAX 180 +#define KILLS_RANGE_MIN 165 +#define KILLS_RANGE_MAX 205 +#define DIVIDER_POS 215 +#define DEATHS_RANGE_MIN 220 +#define DEATHS_RANGE_MAX 245 +#define PING_RANGE_MIN 280 +#define PING_RANGE_MAX 330 +#define PL_RANGE_MIN 350 +#define PL_RANGE_MAX 410 int SCOREBOARD_WIDTH = 320; From 3dda2ec590a305bea7023f98bb0c6da30c02c7d6 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 28 Dec 2017 02:02:23 +0300 Subject: [PATCH 142/211] Fix compiling on MSVC2017 --- cl_dll/CMakeLists.txt | 19 +++++++++++++++---- dlls/CMakeLists.txt | 11 +++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 2d247950..824acc52 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -25,11 +25,22 @@ project (CLDLL) set (CLDLL_LIBRARY client) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w") -if (GOLDSOURCE_SUPPORT) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGOLDSOURCE_SUPPORT") + +add_definitions(-DCLIENT_WEAPONS -DCLIENT_DLL) + +if(NOT WIN32) + add_compile_options(-fno-exceptions) # GCC/Clang flag + add_compile_options(-Wno-write-strings) # GCC/Clang flag + add_definitions(-D_LINUX -DLINUX) # It seems enough for all non-Win32 systems + add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf ) +else() + add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) endif() -set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") + +if (GOLDSOURCE_SUPPORT) + add_definitions(-DGOLDSOURCE_SUPPORT) +endif() + set (CLDLL_SOURCES ../dlls/crossbow.cpp diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index 480b61d1..1564b90e 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -25,8 +25,15 @@ project (SVDLL) set (SVDLL_LIBRARY server) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LINUX -DCLIENT_WEAPONS -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -fno-exceptions -w") -set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") +add_definitions(-DCLIENT_WEAPONS) + +if(NOT WIN32) + add_compile_options(-fno-exceptions) # GCC/Clang flag + add_definitions(-D_LINUX) # It seems enough for all non-Win32 systems + add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf ) +else() + add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) +endif() set (SVDLL_SOURCES agrunt.cpp From 9a02d7116fc0d6dd89ab0f6f2e54e18eb6ecac8e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 28 Dec 2017 02:05:47 +0300 Subject: [PATCH 143/211] It's better to use MSVC here instead of WIN32, so it wouldn't break MinGW builds --- cl_dll/CMakeLists.txt | 2 +- dlls/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 824acc52..05990913 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -28,7 +28,7 @@ set (CLDLL_LIBRARY client) add_definitions(-DCLIENT_WEAPONS -DCLIENT_DLL) -if(NOT WIN32) +if(NOT MSVC) add_compile_options(-fno-exceptions) # GCC/Clang flag add_compile_options(-Wno-write-strings) # GCC/Clang flag add_definitions(-D_LINUX -DLINUX) # It seems enough for all non-Win32 systems diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index 1564b90e..bf65b00f 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -27,7 +27,7 @@ set (SVDLL_LIBRARY server) add_definitions(-DCLIENT_WEAPONS) -if(NOT WIN32) +if(NOT MSVC) add_compile_options(-fno-exceptions) # GCC/Clang flag add_definitions(-D_LINUX) # It seems enough for all non-Win32 systems add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf ) From c5aa3aa40e461042425a171b121df2e043d8d3d4 Mon Sep 17 00:00:00 2001 From: mittorn Date: Sat, 30 Dec 2017 22:22:14 +0700 Subject: [PATCH 144/211] Fix amd64 build --- dlls/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/util.h b/dlls/util.h index 7f9dea70..41e86a84 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -40,7 +40,7 @@ extern globalvars_t *gpGlobals; #define STRING(offset) (const char *)(gpGlobals->pStringBase + (int)offset) #if !defined XASH_64BIT || defined(CLIENT_DLL) -#define MAKE_STRING(str) ((int)str - (int)STRING(0)) +#define MAKE_STRING(str) ((int)(long int)str - (int)(long int)STRING(0)) #else static inline int MAKE_STRING(const char *szValue) { From 8abffc937138ad9e84132259b81683f25f127286 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sat, 13 Jan 2018 09:01:38 +0500 Subject: [PATCH 145/211] Fix typo. --- dlls/util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/util.cpp b/dlls/util.cpp index 94c8c68c..c7feab31 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -989,7 +989,7 @@ float UTIL_Approach( float target, float value, float speed ) float UTIL_ApproachAngle( float target, float value, float speed ) { target = UTIL_AngleMod( target ); - value = UTIL_AngleMod( target ); + value = UTIL_AngleMod( value ); float delta = target - value; From 31c1e121b5826245e1ec074f83d4e3636cef7891 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sat, 13 Jan 2018 18:03:24 +0300 Subject: [PATCH 146/211] Fix some warnings. Disable warning about invalid offsetof as it produces billion warnings in save-restore code --- dlls/CMakeLists.txt | 4 ++-- dlls/playermonster.cpp | 4 ++-- utils/false_vgui/include/VGUI_Panel.h | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index bf65b00f..bfd7d80b 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -1,4 +1,4 @@ -# +# # Copyright (c) 2015 Pavlo Lavrenenko # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -28,7 +28,7 @@ set (SVDLL_LIBRARY server) add_definitions(-DCLIENT_WEAPONS) if(NOT MSVC) - add_compile_options(-fno-exceptions) # GCC/Clang flag + add_compile_options(-fno-exceptions -Wno-invalid-offsetof) # GCC/Clang flag add_definitions(-D_LINUX) # It seems enough for all non-Win32 systems add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf ) else() diff --git a/dlls/playermonster.cpp b/dlls/playermonster.cpp index cd3484ab..a6e38389 100644 --- a/dlls/playermonster.cpp +++ b/dlls/playermonster.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // @@ -82,7 +82,7 @@ void CPlayerMonster :: HandleAnimEvent( MonsterEvent_t *pEvent ) //========================================================= int CPlayerMonster::ISoundMask( void ) { - return NULL; + return 0; } //========================================================= diff --git a/utils/false_vgui/include/VGUI_Panel.h b/utils/false_vgui/include/VGUI_Panel.h index bec7ac25..351b2375 100644 --- a/utils/false_vgui/include/VGUI_Panel.h +++ b/utils/false_vgui/include/VGUI_Panel.h @@ -219,7 +219,6 @@ private: bool _paintBorderEnabled; bool _paintBackgroundEnabled; bool _paintEnabled; -friend class Panel; friend class App; friend class SurfaceBase; friend class Image; From c13546377453d78c120d41d2b91326d3267e0a94 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Mon, 15 Jan 2018 02:43:57 +0300 Subject: [PATCH 147/211] add_compile_options for older cmake versions --- CMakeLists.txt | 10 ++++++++++ dlls/CMakeLists.txt | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d754eb5..e025342a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,16 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8) endif() endif() +# add_compile_options for older cmake versions +if(${CMAKE_VERSION} VERSION_LESS "3.0.2") +macro(add_compile_options) + set(list_var "${ARGV}") + foreach(arg IN LISTS list_var) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${arg}") + endforeach() +endmacro() +endif() + if(BUILD_CLIENT) add_subdirectory(cl_dll) endif() diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index bfd7d80b..bf7d3370 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -1,4 +1,4 @@ -# +# # Copyright (c) 2015 Pavlo Lavrenenko # # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -28,7 +28,8 @@ set (SVDLL_LIBRARY server) add_definitions(-DCLIENT_WEAPONS) if(NOT MSVC) - add_compile_options(-fno-exceptions -Wno-invalid-offsetof) # GCC/Clang flag + add_compile_options(-fno-exceptions) # GCC/Clang flag + add_compile_options(-Wno-invalid-offsetof) # GCC/Clang flag add_definitions(-D_LINUX) # It seems enough for all non-Win32 systems add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf ) else() From 8dc9245fe3eba4db5b8d44bc094b95b2273b462b Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 18 Jan 2018 22:36:32 +0300 Subject: [PATCH 148/211] Copyright symbol to utf-8 --- cl_dll/GameStudioModelRenderer.cpp | 2 +- cl_dll/GameStudioModelRenderer.h | 2 +- cl_dll/GameStudioModelRenderer_Sample.cpp | 2 +- cl_dll/GameStudioModelRenderer_Sample.h | 2 +- cl_dll/StudioModelRenderer.cpp | 2 +- cl_dll/StudioModelRenderer.h | 2 +- cl_dll/camera.h | 2 +- cl_dll/demo.h | 2 +- cl_dll/entity.cpp | 2 +- cl_dll/ev_hldm.h | 2 +- cl_dll/events.cpp | 2 +- cl_dll/eventscripts.h | 2 +- cl_dll/hud_iface.h | 2 +- cl_dll/hud_servers.cpp | 2 +- cl_dll/hud_servers.h | 2 +- cl_dll/hud_servers_priv.h | 2 +- cl_dll/hud_spectator.cpp | 2 +- cl_dll/hud_spectator.h | 2 +- cl_dll/in_camera.cpp | 2 +- cl_dll/in_defs.h | 2 +- cl_dll/input.cpp | 2 +- cl_dll/kbutton.h | 2 +- cl_dll/overview.cpp | 2 +- cl_dll/overview.h | 2 +- cl_dll/studio_util.cpp | 2 +- cl_dll/studio_util.h | 2 +- cl_dll/tri.cpp | 2 +- cl_dll/view.cpp | 2 +- cl_dll/view.h | 2 +- dlls/squad.h | 2 +- dlls/stats.cpp | 2 +- pm_shared/pm_movevars.h | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/cl_dll/GameStudioModelRenderer.cpp b/cl_dll/GameStudioModelRenderer.cpp index c7211752..f2953e96 100644 --- a/cl_dll/GameStudioModelRenderer.cpp +++ b/cl_dll/GameStudioModelRenderer.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/GameStudioModelRenderer.h b/cl_dll/GameStudioModelRenderer.h index 881dd144..8b911db8 100644 --- a/cl_dll/GameStudioModelRenderer.h +++ b/cl_dll/GameStudioModelRenderer.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/GameStudioModelRenderer_Sample.cpp b/cl_dll/GameStudioModelRenderer_Sample.cpp index d697d927..5f1d2b69 100644 --- a/cl_dll/GameStudioModelRenderer_Sample.cpp +++ b/cl_dll/GameStudioModelRenderer_Sample.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/GameStudioModelRenderer_Sample.h b/cl_dll/GameStudioModelRenderer_Sample.h index 9c09374b..a9136880 100644 --- a/cl_dll/GameStudioModelRenderer_Sample.h +++ b/cl_dll/GameStudioModelRenderer_Sample.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/StudioModelRenderer.cpp b/cl_dll/StudioModelRenderer.cpp index b7c3c1c6..ffcf305b 100644 --- a/cl_dll/StudioModelRenderer.cpp +++ b/cl_dll/StudioModelRenderer.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/StudioModelRenderer.h b/cl_dll/StudioModelRenderer.h index cbfd0d3b..0f91122d 100644 --- a/cl_dll/StudioModelRenderer.h +++ b/cl_dll/StudioModelRenderer.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/camera.h b/cl_dll/camera.h index 69a00216..99235ed6 100644 --- a/cl_dll/camera.h +++ b/cl_dll/camera.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/demo.h b/cl_dll/demo.h index b7dbaff0..def3616a 100644 --- a/cl_dll/demo.h +++ b/cl_dll/demo.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/entity.cpp b/cl_dll/entity.cpp index 303a9d25..344d1783 100644 --- a/cl_dll/entity.cpp +++ b/cl_dll/entity.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/ev_hldm.h b/cl_dll/ev_hldm.h index 88b221df..ffb1190a 100644 --- a/cl_dll/ev_hldm.h +++ b/cl_dll/ev_hldm.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/events.cpp b/cl_dll/events.cpp index a51dd72f..a6d21a69 100644 --- a/cl_dll/events.cpp +++ b/cl_dll/events.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/eventscripts.h b/cl_dll/eventscripts.h index c11ee338..c4d831e0 100644 --- a/cl_dll/eventscripts.h +++ b/cl_dll/eventscripts.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_iface.h b/cl_dll/hud_iface.h index 7993bd9d..ae73fc70 100644 --- a/cl_dll/hud_iface.h +++ b/cl_dll/hud_iface.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_servers.cpp b/cl_dll/hud_servers.cpp index 67973c75..9f940025 100644 --- a/cl_dll/hud_servers.cpp +++ b/cl_dll/hud_servers.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_servers.h b/cl_dll/hud_servers.h index 33fb72a5..59c60f4c 100644 --- a/cl_dll/hud_servers.h +++ b/cl_dll/hud_servers.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_servers_priv.h b/cl_dll/hud_servers_priv.h index d26b3655..c5c9b18e 100644 --- a/cl_dll/hud_servers_priv.h +++ b/cl_dll/hud_servers_priv.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_spectator.cpp b/cl_dll/hud_spectator.cpp index 5ffce74a..8f470c0a 100644 --- a/cl_dll/hud_spectator.cpp +++ b/cl_dll/hud_spectator.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_spectator.h b/cl_dll/hud_spectator.h index 7a9ec9d3..2993c3f2 100644 --- a/cl_dll/hud_spectator.h +++ b/cl_dll/hud_spectator.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/in_camera.cpp b/cl_dll/in_camera.cpp index 92051afe..cf5489c0 100644 --- a/cl_dll/in_camera.cpp +++ b/cl_dll/in_camera.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/in_defs.h b/cl_dll/in_defs.h index d5c352fa..5b6d7a41 100644 --- a/cl_dll/in_defs.h +++ b/cl_dll/in_defs.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/input.cpp b/cl_dll/input.cpp index fd1ef7da..10014082 100644 --- a/cl_dll/input.cpp +++ b/cl_dll/input.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/kbutton.h b/cl_dll/kbutton.h index 54f1ea93..55fbeee6 100644 --- a/cl_dll/kbutton.h +++ b/cl_dll/kbutton.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/overview.cpp b/cl_dll/overview.cpp index 881812f7..ddfb3cd5 100644 --- a/cl_dll/overview.cpp +++ b/cl_dll/overview.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/overview.h b/cl_dll/overview.h index 59535fb4..88a7a047 100644 --- a/cl_dll/overview.h +++ b/cl_dll/overview.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/studio_util.cpp b/cl_dll/studio_util.cpp index a5eb39f1..d3a031d4 100644 --- a/cl_dll/studio_util.cpp +++ b/cl_dll/studio_util.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/studio_util.h b/cl_dll/studio_util.h index 7af94672..90c84fb4 100644 --- a/cl_dll/studio_util.h +++ b/cl_dll/studio_util.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/tri.cpp b/cl_dll/tri.cpp index 517ef982..6bb4edbe 100644 --- a/cl_dll/tri.cpp +++ b/cl_dll/tri.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index a4abe91c..bda8616d 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/view.h b/cl_dll/view.h index c0aa0e8f..7d8624c9 100644 --- a/cl_dll/view.h +++ b/cl_dll/view.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/dlls/squad.h b/dlls/squad.h index f8f20aa0..607540cf 100644 --- a/dlls/squad.h +++ b/dlls/squad.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // diff --git a/dlls/stats.cpp b/dlls/stats.cpp index 1df298b2..48804a16 100644 --- a/dlls/stats.cpp +++ b/dlls/stats.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // diff --git a/pm_shared/pm_movevars.h b/pm_shared/pm_movevars.h index 61eb06fd..19b46b1d 100644 --- a/pm_shared/pm_movevars.h +++ b/pm_shared/pm_movevars.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // From 48733fd1a1a5e10b1029b8099d118ee2d4ce63ec Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Fri, 19 Jan 2018 20:00:32 +0300 Subject: [PATCH 149/211] All copyright symbols to (c) --- cl_dll/GameStudioModelRenderer.cpp | 2 +- cl_dll/GameStudioModelRenderer.h | 2 +- cl_dll/GameStudioModelRenderer_Sample.cpp | 2 +- cl_dll/GameStudioModelRenderer_Sample.h | 2 +- cl_dll/StudioModelRenderer.cpp | 2 +- cl_dll/StudioModelRenderer.h | 2 +- cl_dll/camera.h | 2 +- cl_dll/demo.h | 2 +- cl_dll/entity.cpp | 2 +- cl_dll/ev_hldm.h | 2 +- cl_dll/events.cpp | 2 +- cl_dll/eventscripts.h | 2 +- cl_dll/hud_iface.h | 2 +- cl_dll/hud_servers.cpp | 2 +- cl_dll/hud_servers.h | 2 +- cl_dll/hud_servers_priv.h | 2 +- cl_dll/hud_spectator.cpp | 2 +- cl_dll/hud_spectator.h | 2 +- cl_dll/in_camera.cpp | 2 +- cl_dll/in_defs.h | 2 +- cl_dll/input.cpp | 2 +- cl_dll/input_goldsource.cpp | 2 +- cl_dll/kbutton.h | 2 +- cl_dll/overview.cpp | 2 +- cl_dll/overview.h | 2 +- cl_dll/studio_util.cpp | 2 +- cl_dll/studio_util.h | 2 +- cl_dll/tri.cpp | 2 +- cl_dll/view.cpp | 2 +- cl_dll/view.h | 2 +- dlls/playermonster.cpp | 2 +- dlls/squad.h | 2 +- dlls/stats.cpp | 2 +- pm_shared/pm_movevars.h | 2 +- 34 files changed, 34 insertions(+), 34 deletions(-) diff --git a/cl_dll/GameStudioModelRenderer.cpp b/cl_dll/GameStudioModelRenderer.cpp index f2953e96..570b3375 100644 --- a/cl_dll/GameStudioModelRenderer.cpp +++ b/cl_dll/GameStudioModelRenderer.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/GameStudioModelRenderer.h b/cl_dll/GameStudioModelRenderer.h index 8b911db8..0e424576 100644 --- a/cl_dll/GameStudioModelRenderer.h +++ b/cl_dll/GameStudioModelRenderer.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/GameStudioModelRenderer_Sample.cpp b/cl_dll/GameStudioModelRenderer_Sample.cpp index 5f1d2b69..ee8e8f9c 100644 --- a/cl_dll/GameStudioModelRenderer_Sample.cpp +++ b/cl_dll/GameStudioModelRenderer_Sample.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/GameStudioModelRenderer_Sample.h b/cl_dll/GameStudioModelRenderer_Sample.h index a9136880..7a4d062d 100644 --- a/cl_dll/GameStudioModelRenderer_Sample.h +++ b/cl_dll/GameStudioModelRenderer_Sample.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/StudioModelRenderer.cpp b/cl_dll/StudioModelRenderer.cpp index ffcf305b..a9859244 100644 --- a/cl_dll/StudioModelRenderer.cpp +++ b/cl_dll/StudioModelRenderer.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/StudioModelRenderer.h b/cl_dll/StudioModelRenderer.h index 0f91122d..69d28a1e 100644 --- a/cl_dll/StudioModelRenderer.h +++ b/cl_dll/StudioModelRenderer.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/camera.h b/cl_dll/camera.h index 99235ed6..1ecb9563 100644 --- a/cl_dll/camera.h +++ b/cl_dll/camera.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/demo.h b/cl_dll/demo.h index def3616a..3aaa3f21 100644 --- a/cl_dll/demo.h +++ b/cl_dll/demo.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/entity.cpp b/cl_dll/entity.cpp index 344d1783..40649fa7 100644 --- a/cl_dll/entity.cpp +++ b/cl_dll/entity.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/ev_hldm.h b/cl_dll/ev_hldm.h index ffb1190a..8a836762 100644 --- a/cl_dll/ev_hldm.h +++ b/cl_dll/ev_hldm.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/events.cpp b/cl_dll/events.cpp index a6d21a69..f286d261 100644 --- a/cl_dll/events.cpp +++ b/cl_dll/events.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/eventscripts.h b/cl_dll/eventscripts.h index c4d831e0..c61bf300 100644 --- a/cl_dll/eventscripts.h +++ b/cl_dll/eventscripts.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_iface.h b/cl_dll/hud_iface.h index ae73fc70..73464c83 100644 --- a/cl_dll/hud_iface.h +++ b/cl_dll/hud_iface.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_servers.cpp b/cl_dll/hud_servers.cpp index 9f940025..fa6d5585 100644 --- a/cl_dll/hud_servers.cpp +++ b/cl_dll/hud_servers.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_servers.h b/cl_dll/hud_servers.h index 59c60f4c..5e886560 100644 --- a/cl_dll/hud_servers.h +++ b/cl_dll/hud_servers.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_servers_priv.h b/cl_dll/hud_servers_priv.h index c5c9b18e..72590c2f 100644 --- a/cl_dll/hud_servers_priv.h +++ b/cl_dll/hud_servers_priv.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_spectator.cpp b/cl_dll/hud_spectator.cpp index 8f470c0a..edb743ba 100644 --- a/cl_dll/hud_spectator.cpp +++ b/cl_dll/hud_spectator.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/hud_spectator.h b/cl_dll/hud_spectator.h index 2993c3f2..9b3391e2 100644 --- a/cl_dll/hud_spectator.h +++ b/cl_dll/hud_spectator.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/in_camera.cpp b/cl_dll/in_camera.cpp index cf5489c0..12ad41f4 100644 --- a/cl_dll/in_camera.cpp +++ b/cl_dll/in_camera.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/in_defs.h b/cl_dll/in_defs.h index 5b6d7a41..b4c51730 100644 --- a/cl_dll/in_defs.h +++ b/cl_dll/in_defs.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/input.cpp b/cl_dll/input.cpp index 10014082..0abd542b 100644 --- a/cl_dll/input.cpp +++ b/cl_dll/input.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index f530bdbc..bd997784 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/kbutton.h b/cl_dll/kbutton.h index 55fbeee6..4c7c7ae8 100644 --- a/cl_dll/kbutton.h +++ b/cl_dll/kbutton.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/overview.cpp b/cl_dll/overview.cpp index ddfb3cd5..81f028e2 100644 --- a/cl_dll/overview.cpp +++ b/cl_dll/overview.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/overview.h b/cl_dll/overview.h index 88a7a047..c1675e98 100644 --- a/cl_dll/overview.h +++ b/cl_dll/overview.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/studio_util.cpp b/cl_dll/studio_util.cpp index d3a031d4..6e488dcb 100644 --- a/cl_dll/studio_util.cpp +++ b/cl_dll/studio_util.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/studio_util.h b/cl_dll/studio_util.h index 90c84fb4..83de704c 100644 --- a/cl_dll/studio_util.h +++ b/cl_dll/studio_util.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/tri.cpp b/cl_dll/tri.cpp index 6bb4edbe..ab8f3730 100644 --- a/cl_dll/tri.cpp +++ b/cl_dll/tri.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index bda8616d..daecc3af 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/cl_dll/view.h b/cl_dll/view.h index 7d8624c9..6ca818d5 100644 --- a/cl_dll/view.h +++ b/cl_dll/view.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/dlls/playermonster.cpp b/dlls/playermonster.cpp index a6e38389..092e7dca 100644 --- a/dlls/playermonster.cpp +++ b/dlls/playermonster.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // diff --git a/dlls/squad.h b/dlls/squad.h index 607540cf..2c79ee90 100644 --- a/dlls/squad.h +++ b/dlls/squad.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // diff --git a/dlls/stats.cpp b/dlls/stats.cpp index 48804a16..e37832c8 100644 --- a/dlls/stats.cpp +++ b/dlls/stats.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // diff --git a/pm_shared/pm_movevars.h b/pm_shared/pm_movevars.h index 19b46b1d..53d8ee9c 100644 --- a/pm_shared/pm_movevars.h +++ b/pm_shared/pm_movevars.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // From 53626b99652070e7e54767cb827afb3d96169aeb Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sat, 20 Jan 2018 17:03:53 +0300 Subject: [PATCH 150/211] Add custom makefont from #46 --- utils/makefont/makefont.cpp | 845 ++++++++++++++++++++++++++++++++++++ utils/makefont/makefont.dsp | 138 ++++++ utils/makefont/winebuild.sh | 3 + 3 files changed, 986 insertions(+) create mode 100644 utils/makefont/makefont.cpp create mode 100644 utils/makefont/makefont.dsp create mode 100755 utils/makefont/winebuild.sh diff --git a/utils/makefont/makefont.cpp b/utils/makefont/makefont.cpp new file mode 100644 index 00000000..eb2eb3ff --- /dev/null +++ b/utils/makefont/makefont.cpp @@ -0,0 +1,845 @@ +/*** +* +* Copyright (c) 1996-2002, Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ + +#define _NOENUMQBOOL + +#include + +extern "C" +{ + #include "cmdlib.h" + #include "wadlib.h" +} +#include "qfont.h" + +#define DEFAULT_FONT "Arial" + +#define FONT_TAG 6 // Font's are the 6th tag after the TYP_LUMPY base ( 64 )...i.e., type == 70 + +BOOL bItalic = FALSE; +BOOL bBold = FALSE; +BOOL bUnderline = FALSE; + +char fontname[ 256 ]; +int pointsize[3] = { 9, 11, 15 }; + +/* +================= +zeromalloc + +Allocates and zeroes memory +================= +*/ +void *zeromalloc( size_t size ) +{ + unsigned char *pbuffer; + pbuffer = ( unsigned char * )malloc( size ); + if ( !pbuffer ) + { + printf( "Failed on allocation of %i bytes", size ); + exit( -1 ); + } + + memset( pbuffer, 0, size ); + return ( void * )pbuffer; +} + +/* +================= +Draw_SetupConsolePalette + +Set's the palette to full brightness ( 192 ) and +set's up palette entry 0 -- black +================= +*/ +void Draw_SetupConsolePalette( unsigned char *pal ) +{ + unsigned char *pPalette; + int i; + + pPalette = pal; + + *(short *)pPalette = 3 * 256; + pPalette += sizeof( short ); + + for ( i = 0; i < 256; i++ ) + { + pPalette[3 * i + 0 ] = i; + pPalette[3 * i + 1 ] = i; + pPalette[3 * i + 2 ] = i; + } + + // Set palette zero correctly + pPalette[ 0 ] = 0; + pPalette[ 1 ] = 0; + pPalette[ 2 ] = 0; +} + +//DJXX added for debugging +BOOL WriteDIB(LPTSTR szFile, HANDLE hDIB) +{ + BITMAPFILEHEADER hdr; + LPBITMAPINFOHEADER lpbi; + + if (!hDIB) + return FALSE; + + FILE *file; + file = SafeOpenWrite(szFile); + + + lpbi = (LPBITMAPINFOHEADER)hDIB; + + int nColors = 1 << lpbi->biBitCount; + + // Fill in the fields of the file header + hdr.bfType = ((WORD)('M' << 8) | 'B'); // is always "BM" + hdr.bfSize = GlobalSize(hDIB) + sizeof(hdr); + printf("WriteDIB. Error code = %i\n",GetLastError()); + hdr.bfReserved1 = 0; + hdr.bfReserved2 = 0; + hdr.bfOffBits = (DWORD)(sizeof(hdr)+lpbi->biSize + + nColors * sizeof(RGBQUAD)); + + // Write the file header + SafeWrite(file, &hdr, sizeof(hdr)); + + // Write the DIB header and the bits + SafeWrite(file, lpbi, GlobalSize(hDIB)); + fclose(file); + return TRUE; +} + + +/* +================= +CreateProportionalConsoleFont + +Renders TT font into memory dc and creates appropriate qfont_t structure +================= +*/ +//DJXX: New version, draws chararacters closely to each other without spaces + +// YWB: Sigh, VC 6.0's global optimizer causes weird stack fixups in release builds. Disable the globabl optimizer for this function. +#pragma optimize( "g", off ) +qfont_t *CreateProportionalConsoleFont(char *pszFont, int nPointSize, BOOL bItalic, BOOL bUnderline, BOOL bBold, int *outsize) +{ + HDC hdc; + HDC hmemDC; + HBITMAP hbm, oldbm; + RECT rc; + HFONT fnt, oldfnt; + TEXTMETRIC tm; + int startchar = 32; + int c; + int i, j; + int x, y; + int nScans; + unsigned char *bits; + BITMAPINFO tempbmi; + BITMAPINFO *pbmi; + BITMAPINFOHEADER *pbmheader; + unsigned char *pqdata; + unsigned char *pCur; + int x1, y1; + unsigned char *pPalette; + qfont_t *pqf = NULL; + int fullsize; + int w = 16; + //int h = (128 - 32) / 16; + int h = (256 - 32) / 16; + int charheight = nPointSize + 5; + int charwidth = 16;//now used only for calculating width of wad texture + int fontcharwidth; + int edge = 1; + RECT rcChar; + boolean lShadow = true;//draw shadow instead of outline + + // Create the font + fnt = CreateFont(-nPointSize, 0, 0, 0, bBold ? FW_HEAVY : FW_MEDIUM, bItalic, bUnderline, 0, /*ANSI_CHARSET*/DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_DONTCARE, pszFont); + + bits = NULL; + + fullsize = sizeof(qfont_t)-4 + (/*128*/256 * w * charwidth) + sizeof(short)+768 + 64; + + // Store off final size + *outsize = fullsize; + + pqf = (qfont_t *)zeromalloc(fullsize); + pqdata = (unsigned char *)pqf + sizeof(qfont_t)-4; + + pPalette = pqdata + (/*128*/256 * w * charwidth); + + // Configure palette + Draw_SetupConsolePalette(pPalette); + + hdc = GetDC(NULL); + hmemDC = CreateCompatibleDC(hdc); + + oldfnt = (HFONT)SelectObject(hmemDC, fnt); + + if (GetTextMetrics(hmemDC, &tm)) + { + fontcharwidth = tm.tmMaxCharWidth; + if (fontcharwidth % 2)//hack: on odd values of fontcharwidth, bitmaps pixel check gives false triggering + fontcharwidth++; + } + else { + fontcharwidth = charwidth; + } + + if (lShadow) + charheight += edge;//adding 1 pixel to bottom for shadowing + + rc.top = 0; + rc.left = 0; + rc.right = fontcharwidth * w; + rc.bottom = charheight * h; + + hbm = CreateBitmap(fontcharwidth * w, charheight * h, 1, 1, NULL); + oldbm = (HBITMAP)SelectObject(hmemDC, hbm); + + SetTextColor(hmemDC, 0x00ffffff); + SetBkMode(hmemDC, TRANSPARENT); + + // Paint black background + FillRect(hmemDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH)); + + // Draw character set into memory DC + for (j = 0; j < h; j++) + { + for (i = 0; i < w; i++) + { + x = i * fontcharwidth; + y = j * charheight; + + c = (unsigned char)(startchar + j * w + i); + + // Only draw printable characters, of course + //if ( isprint( c ) && c <= 127 ) + { + // Draw it. + rcChar.left = x + 1; + rcChar.top = y + 1; + rcChar.right = x + fontcharwidth - 1; + rcChar.bottom = y + charheight - 1; + + DrawText(hmemDC, (char *)&c, 1, &rcChar, DT_NOPREFIX | DT_LEFT); + } + } + } + + // Now turn the qfont into raw format + memset(&tempbmi, 0, sizeof(BITMAPINFO)); + + pbmheader = (BITMAPINFOHEADER *)&tempbmi; + + pbmheader->biSize = sizeof(BITMAPINFOHEADER); + pbmheader->biWidth = w * fontcharwidth; + pbmheader->biHeight = -h * charheight; + pbmheader->biPlanes = 1; + pbmheader->biBitCount = 1; + pbmheader->biCompression = BI_RGB; + + // Find out how big the bitmap is + nScans = GetDIBits(hmemDC, hbm, 0, h * charheight, NULL, &tempbmi, DIB_RGB_COLORS); + + // Allocate space for all bits + pbmi = (BITMAPINFO *)zeromalloc(sizeof (BITMAPINFOHEADER)+2 * sizeof(RGBQUAD)+pbmheader->biSizeImage); + + memcpy(pbmi, &tempbmi, sizeof(BITMAPINFO)); + + bits = (unsigned char *)pbmi + sizeof(BITMAPINFOHEADER)+2 * sizeof(RGBQUAD); + + // Now read in bits + nScans = GetDIBits(hmemDC, hbm, 0, h * charheight, bits, pbmi, DIB_RGB_COLORS); + + if (nScans > 0) + { +#if 0 //for debugging + char sz[128];//DJXX write dib to file + sprintf(sz, "font_%s_%i.bmp", pszFont, nPointSize); + WriteDIB(sz, pbmi); +#endif + // Now convert to proper raw format + // + // Now get results from dib + pqf->height = /*128*/256; // Always set to 128 + pqf->width = charwidth; + pqf->rowheight = charheight; + pqf->rowcount = h; + pCur = pqdata; + + // Set everything to index 255 ( 0xff ) == transparent + memset(pCur, 0xFF, w * charwidth * pqf->height); + + int k = 0, dest_x = 0, dest_y = 0; + + for (j = 0; j < h; j++) + for (i = 0; i < w; i++) + { + int rightmost, leftmost, realcharwidth; + + x = i * fontcharwidth; + y = j * charheight; + + //c = (char)( startchar + j * w + i ); here was memory bug + c = (unsigned char)(startchar + j * w + i); + + rightmost = 0; + leftmost = fontcharwidth; + + //Calculate real width of the character + for (y1 = 0; y1 < charheight; y1++) + for (x1 = 0; x1 < fontcharwidth; x1++) + { + int src_offset; + + src_offset = (y + y1) * w * fontcharwidth + x + x1; + + if (bits[src_offset >> 3] & (1 << (7 - src_offset & 7)))//on odd values of fontcharwidth this check gives false triggering + { + if (x1 > rightmost) + rightmost = x1; + + if (x1 < leftmost) + leftmost = x1; + } + } + if (leftmost > rightmost)//empty characters + { + leftmost = 0; + rightmost = 7; + } else { + rightmost += edge; + if (!lShadow) + leftmost -= edge; + } + + realcharwidth = rightmost - leftmost + 1; + pqf->fontinfo[c].charwidth = realcharwidth; + + if (dest_x + realcharwidth >= w * charwidth)//if it not fits on current line then carry it to the next line + { + dest_x = 0; + k++; + } + + dest_y = k * charheight; + pqf->fontinfo[c].startoffset = dest_y * w * charwidth + dest_x; + + if (lShadow) + { + int shift = edge; + //Draw shadow by shifting character to 1 pixel right and down + for (y1 = 0; y1 < charheight; y1++) + for (x1 = 0; x1 < realcharwidth; x1++) + { + int src_offset, dest_offset; + + src_offset = (y + y1) * w * fontcharwidth + x + x1 + leftmost; + dest_offset = (dest_y + shift + y1) * w * charwidth + (dest_x + shift + x1); + + // Dest + pCur = pqdata + dest_offset; + + if (bits[src_offset >> 3] & (1 << (7 - src_offset & 7))) + { + // Near Black + //pCur[0] = 32; + pCur[0] = 0;//full black so shadow remains black even it's coloured text + } + } + } + else + { + // Put black pixels below and to the right of each pixel(outline) + for (y1 = edge; y1 < charheight - edge; y1++) + for (x1 = 0; x1 < realcharwidth; x1++) + { + int src_offset, dest_offset; + + int xx0, yy0; + + dest_offset = (dest_y + y1) * w * charwidth + (dest_x + x1); + + // Dest + pCur = pqdata + dest_offset; + + for (xx0 = -edge; xx0 <= edge; xx0++) + for (yy0 = -edge; yy0 <= edge; yy0++) + { + src_offset = (y + y1 + yy0) * w * fontcharwidth + x + x1 + xx0 + leftmost;//adding shift + + if (bits[src_offset >> 3] & (1 << (7 - src_offset & 7))) + { + // Near Black + pCur[0] = 32; + } + } + } + } + + // Now copy in the actual font pixels + for (y1 = 0; y1 < charheight; y1++) + for (x1 = 0; x1 < realcharwidth; x1++) + { + int src_offset, dest_offset; + + src_offset = (y + y1) * w * fontcharwidth + x + x1 + leftmost; + dest_offset = (dest_y + y1) * w * charwidth + (dest_x + x1); + + // Dest + pCur = pqdata + dest_offset; + + if (bits[src_offset >> 3] & (1 << (7 - src_offset & 7))) + { + pCur[0] = 192; + } + } + dest_x += realcharwidth; + } + } + // Free memory bits + free(pbmi); + SelectObject(hmemDC, oldfnt); + DeleteObject(fnt); + + SelectObject(hmemDC, oldbm); + + DeleteObject(hbm); + + DeleteDC(hmemDC); + ReleaseDC(NULL, hdc); + + return pqf; +} +#pragma optimize( "g", on ) + + +/* +================= +CreateConsoleFont + +Renders TT font into memory dc and creates appropriate qfont_t structure +================= +*/ +//DJXX: original version, just added drawing of locale characters and fixed memory bug. +// YWB: Sigh, VC 6.0's global optimizer causes weird stack fixups in release builds. Disable the globabl optimizer for this function. +#pragma optimize( "g", off ) +qfont_t *CreateConsoleFont( char *pszFont, int nPointSize, BOOL bItalic, BOOL bUnderline, BOOL bBold, int *outsize ) +{ + HDC hdc; + HDC hmemDC; + HBITMAP hbm, oldbm; + RECT rc; + HFONT fnt, oldfnt; + int startchar = 32; + int c; + int i, j; + int x, y; + int nScans; + unsigned char *bits; + BITMAPINFO tempbmi; + BITMAPINFO *pbmi; + BITMAPINFOHEADER *pbmheader; + unsigned char *pqdata; + unsigned char *pCur; + int x1, y1; + unsigned char *pPalette; + qfont_t *pqf = NULL; + int fullsize; + int w = 16; + //int h = (128-32)/16; + int h = (256 - 32) / 16; + int charheight = nPointSize + 5; + int charwidth = 16; + RECT rcChar; + + // Create the font + fnt = CreateFont( -nPointSize, 0, 0, 0, bBold ? FW_HEAVY : FW_MEDIUM, bItalic, bUnderline, 0, /*ANSI_CHARSET*/DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_DONTCARE, pszFont ); + + bits = NULL; + + fullsize = sizeof( qfont_t ) - 4 + ( /*128*/256 * w * charwidth ) + sizeof(short) + 768 + 64; + + // Store off final size + *outsize = fullsize; + + pqf = ( qfont_t * )zeromalloc( fullsize ); + pqdata = (unsigned char *)pqf + sizeof( qfont_t ) - 4; + + pPalette = pqdata + ( /*128*/256 * w * charwidth); + + // Configure palette + Draw_SetupConsolePalette( pPalette ); + + hdc = GetDC( NULL ); + hmemDC = CreateCompatibleDC( hdc ); + + rc.top = 0; + rc.left = 0; + rc.right = charwidth * w; + rc.bottom = charheight * h; + + hbm = CreateBitmap( charwidth * w, charheight * h, 1, 1, NULL ); + oldbm = (HBITMAP)SelectObject( hmemDC, hbm ); + oldfnt = (HFONT)SelectObject( hmemDC, fnt ); + + SetTextColor( hmemDC, 0x00ffffff ); + SetBkMode( hmemDC, TRANSPARENT ); + + // Paint black background + FillRect( hmemDC, &rc, (HBRUSH)GetStockObject( BLACK_BRUSH ) ); + + // Draw character set into memory DC + for ( j = 0; j < h; j++ ) + { + for ( i = 0; i < w; i++ ) + { + x = i * charwidth; + y = j * charheight; + + c = (unsigned char)( startchar + j * w + i ); + + // Only draw printable characters, of course + //if ( isprint( c ) && c <= 127 ) + { + // Draw it. + rcChar.left = x + 1; + rcChar.top = y + 1; + rcChar.right = x + charwidth - 1; + rcChar.bottom = y + charheight - 1; + + DrawText( hmemDC, (char *)&c, 1, &rcChar, DT_NOPREFIX | DT_LEFT ); + } + } + } + + // Now turn the qfont into raw format + memset( &tempbmi, 0, sizeof( BITMAPINFO ) ); + pbmheader = ( BITMAPINFOHEADER * )&tempbmi; + + pbmheader->biSize = sizeof( BITMAPINFOHEADER ); + pbmheader->biWidth = w * charwidth; + pbmheader->biHeight = -h * charheight; + pbmheader->biPlanes = 1; + pbmheader->biBitCount = 1; + pbmheader->biCompression = BI_RGB; + + // Find out how big the bitmap is + nScans = GetDIBits( hmemDC, hbm, 0, h * charheight, NULL, &tempbmi, DIB_RGB_COLORS ); + + // Allocate space for all bits + pbmi = ( BITMAPINFO * )zeromalloc( sizeof ( BITMAPINFOHEADER ) + 2 * sizeof( RGBQUAD ) + pbmheader->biSizeImage ); + + memcpy( pbmi, &tempbmi, sizeof( BITMAPINFO ) ); + + bits = ( unsigned char * )pbmi + sizeof( BITMAPINFOHEADER ) + 2 * sizeof( RGBQUAD ); + + // Now read in bits + nScans = GetDIBits( hmemDC, hbm, 0, h * charheight, bits, pbmi, DIB_RGB_COLORS ); + + if ( nScans > 0 ) + { +#if 0 //for debugging + char sz[128];//DJXX write dib to file + sprintf(sz, "font_%s_%i.bmp", pszFont, nPointSize); + WriteDIB(sz, pbmi); +#endif + + // Now convert to proper raw format + // + // Now get results from dib + pqf->height = /*128*/256; // Always set to 128 + pqf->width = charwidth; + pqf->rowheight = charheight; + pqf->rowcount = h; + pCur = pqdata; + + // Set everything to index 255 ( 0xff ) == transparent + memset( pCur, 0xFF, w * charwidth * pqf->height ); + + for ( j = 0; j < h; j++ ) + { + for ( i = 0; i < w; i++ ) + { + int edge = 1; + int bestwidth; + x = i * charwidth; + y = j * charheight; + + + //c = (char)( startchar + j * w + i ); here was memory bug + c = (unsigned char)(startchar + j * w + i); + + pqf->fontinfo[ c ].charwidth = charwidth; + pqf->fontinfo[ c ].startoffset = y * w * charwidth + x; + + bestwidth = 0; + + // In this first pass, place the black drop shadow so characters draw ok in the engine against + // most backgrounds. + // YWB: FIXME, apply a box filter and enable blending? +#if 0//DJXX: we already did that for a whole image by memset + // Make it all transparent for starters + for ( y1 = 0; y1 < charheight; y1++ ) + { + for ( x1 = 0; x1 < charwidth; x1++ ) + { + int offset; + offset = ( y + y1 ) * w * charwidth + x + x1 ; + // Dest + pCur = pqdata + offset; + // Assume transparent + pCur[0] = 255; + } + } +#endif + // Put black pixels below and to the right of each pixel + for ( y1 = edge; y1 < charheight - edge; y1++ ) + { + for ( x1 = 0; x1 < charwidth; x1++ ) + { + int offset; + int srcoffset; + + int xx0, yy0; + + offset = ( y + y1 ) * w * charwidth + x + x1 ; + + // Dest + pCur = pqdata + offset; + + for ( xx0 = -edge; xx0 <= edge; xx0++ ) + { + for ( yy0 = -edge; yy0 <= edge; yy0++ ) + { + srcoffset = ( y + y1 + yy0 ) * w * charwidth + x + x1 + xx0; + + if ( bits[ srcoffset >> 3 ] & ( 1 << ( 7 - srcoffset & 7 ) ) ) + { + // Near Black + pCur[0] = 32; + } + } + } + } + } + + // Now copy in the actual font pixels + for ( y1 = 0; y1 < charheight; y1++ ) + { + for ( x1 = 0; x1 < charwidth; x1++ ) + { + int offset; + + offset = ( y + y1 ) * w * charwidth + x + x1; + + // Dest + pCur = pqdata + offset; + + if ( bits[ offset >> 3 ] & ( 1 << ( 7 - offset & 7 ) ) ) + { + if ( x1 > bestwidth ) + { + bestwidth = x1; + } + + // Full color + // FIXME: Enable true palette support in engine? + pCur[0] = 192; + } + } + } + + // bestwidth += 1; + /* + // Now blend it + for ( y1 = 0; y1 < charheight; y1++ ) + { + for ( x1 = 0; x1 < charwidth; x1++ ) + { + int offset; + + offset = ( y + y1 ) * w * charwidth + x + x1; + + // Dest + pCur = pqdata + offset; + + if ( bits[ offset >> 3 ] & ( 1 << ( 7 - offset & 7 ) ) ) + { + if ( x1 > bestwidth ) + { + bestwidth = x1; + } + + // Full color + // FIXME: Enable true palette support in engine? + pCur[0] = 192; + } + } + } + */ + + // Space character width + if ( c == 32 ) + { + bestwidth = 8; + } + else + { + // Small characters needs can be padded a bit so they don't run into each other + if ( bestwidth <= 14 ) + { + bestwidth += 2; + } + } + + // Store off width + pqf->fontinfo[ c ].charwidth = bestwidth; + } + } + } + + // Free memory bits + free ( pbmi ); + + SelectObject( hmemDC, oldfnt ); + DeleteObject( fnt ); + + SelectObject( hmemDC, oldbm ); + + DeleteObject( hbm ); + + DeleteDC( hmemDC ); + ReleaseDC( NULL, hdc ); + + return pqf; +} + +#pragma optimize( "g", on ) + +/* +================= +main + +================= +*/ +int main(int argc, char* argv[]) +{ + int i; + DWORD start, end; + char destfile[1024]; + char sz[ 32 ]; + int outsize[ 3 ]; + + qfont_t *fonts[ 3 ]; + + strcpy( fontname, DEFAULT_FONT ); + + printf("makefont.exe Version 2.0 by valve and DJXX (%s)\n", __DATE__ ); + + printf ("----- Creating Console Font ----\n"); + + for (i=1 ; i= argc ) + { + Error( "Makefont: Insufficient point sizes specified\n" ); + } + pointsize[0] = atoi( argv[i+1] ); + pointsize[1] = atoi( argv[i+2] ); + pointsize[2] = atoi( argv[i+3] ); + i += 3; + } + else if (!strcmp(argv[i],"-italic")) + { + bItalic = TRUE; + printf ( "italic set\n"); + } + else if (!strcmp(argv[i],"-bold")) + { + bBold = TRUE; + printf ( "bold set\n"); + } + else if (!strcmp(argv[i],"-underline")) + { + bUnderline = TRUE; + printf ( "underline set\n"); + } + else if ( argv[i][0] == '-' ) + { + Error ("Unknown option \"%s\"", argv[i]); + } + else + break; + } + + if ( i != argc - 1 ) + { + Error ("usage: makefont [-font \"fontname\"] [-italic] [-underline] [-bold] [-pointsizes sm med lg] outfile"); + } + + printf( "Creating %i, %i, and %i point %s fonts\n", pointsize[0], pointsize[1], pointsize[2], fontname ); + + start = timeGetTime(); + + // Create the fonts + for ( i = 0 ; i < 3; i++ ) + { + fonts[ i ] = CreateProportionalConsoleFont( fontname, pointsize[i], bItalic, bUnderline, bBold, &outsize[ i ] ); + //fonts[i] = CreateConsoleFont(fontname, pointsize[i], bItalic, bUnderline, bBold, &outsize[i]); + } + + // Create wad file + strcpy (destfile, argv[argc - 1]); + StripExtension (destfile); + DefaultExtension (destfile, ".wad"); + + NewWad( destfile, false ); + + // Add fonts as lumps + for ( i = 0; i < 3; i++ ) + { + sprintf( sz, "font%i", i ); + AddLump( sz, fonts[ i ], outsize[ i ], TYP_LUMPY + FONT_TAG, false ); + } + + // Store results as a WAD3 + // NOTE: ( should be named fonts.wad in the valve\ subdirectory ) + WriteWad( 3 ); + + // Clean up memory + for ( i = 0 ; i < 3; i++ ) + { + free( fonts[ i ] ); + } + + end = timeGetTime (); + + printf ( "%5.5f seconds elapsed\n", (float)( end - start )/1000.0 ); + + // Display for a second since it might not be running from command prompt + Sleep( 1000 ); + return 0; +} diff --git a/utils/makefont/makefont.dsp b/utils/makefont/makefont.dsp new file mode 100644 index 00000000..aece6e0c --- /dev/null +++ b/utils/makefont/makefont.dsp @@ -0,0 +1,138 @@ +# Microsoft Developer Studio Project File - Name="makefont" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=makefont - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "makefont.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "makefont.mak" CFG="makefont - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "makefont - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "makefont - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "makefont - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /W3 /GX /Zi /O2 /I "../../common" /I "../common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX"qfont.h" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 +# Begin Special Build Tool +TargetPath=.\Release\makefont.exe +SOURCE="$(InputPath)" +PostBuild_Desc=Copyint to valve\ +PostBuild_Cmds=xcopy $(TargetPath) ..\..\..\valve /r /i +# End Special Build Tool + +!ELSEIF "$(CFG)" == "makefont - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../common" /I "../common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX"qfont.h" /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# Begin Special Build Tool +TargetPath=.\Debug\makefont.exe +SOURCE="$(InputPath)" +PostBuild_Desc=Copyint to valve\ +PostBuild_Cmds=xcopy $(TargetPath) ..\..\..\valve /r /i +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "makefont - Win32 Release" +# Name "makefont - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\common\cmdlib.c +# End Source File +# Begin Source File + +SOURCE=.\makefont.cpp +# End Source File +# Begin Source File + +SOURCE=..\common\wadlib.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\common\cmdlib.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=..\common\wadlib.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/utils/makefont/winebuild.sh b/utils/makefont/winebuild.sh new file mode 100755 index 00000000..ec259577 --- /dev/null +++ b/utils/makefont/winebuild.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +winegcc -g -m32 makefont.cpp ../common/wadlib.c ../common/cmdlib.c -I../common/ -I../../common/ -mwindows -mno-cygwin -lwinmm -fno-stack-protector From 588065ab162693a30569d07089b46d7d17ca66d9 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 15 Feb 2018 17:27:02 +0500 Subject: [PATCH 151/211] Do not show long nicknames on low resolution. --- cl_dll/scoreboard.cpp | 65 ++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index 908d00f3..0f26c6f2 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -92,17 +92,18 @@ We have a minimum width of 1-320 - we could have the field widths scale with it? // X positions // relative to the side of the scoreboard -#define NAME_RANGE_MIN -65 -#define NAME_RANGE_MAX 180 -#define KILLS_RANGE_MIN 165 -#define KILLS_RANGE_MAX 205 -#define DIVIDER_POS 215 -#define DEATHS_RANGE_MIN 220 -#define DEATHS_RANGE_MAX 245 -#define PING_RANGE_MIN 280 -#define PING_RANGE_MAX 330 -#define PL_RANGE_MIN 350 -#define PL_RANGE_MAX 410 +#define NAME_RANGE_MIN 20 +#define NAME_RANGE_MAX 145 +#define NAME_RANGE_MODIFIER 120 +#define KILLS_RANGE_MIN 130 +#define KILLS_RANGE_MAX 170 +#define DIVIDER_POS 180 +#define DEATHS_RANGE_MIN 185 +#define DEATHS_RANGE_MAX 210 +#define PING_RANGE_MIN 245 +#define PING_RANGE_MAX 295 +#define PL_RANGE_MIN 315 +#define PL_RANGE_MAX 375 int SCOREBOARD_WIDTH = 320; @@ -128,11 +129,11 @@ int CHudScoreboard::Draw( float fTime ) if( cl_showpacketloss && cl_showpacketloss->value && ( ScreenWidth >= 400 ) ) { can_show_packetloss = 1; - SCOREBOARD_WIDTH = 400; + SCOREBOARD_WIDTH = ( ScreenWidth >= 520 ) ? ( 400 - NAME_RANGE_MODIFIER ) : 400; } else { - SCOREBOARD_WIDTH = 320; + SCOREBOARD_WIDTH = ( ScreenWidth >= 440 ) ? ( 320 - NAME_RANGE_MODIFIER ) : 320; } // just sort the list on the fly @@ -145,7 +146,14 @@ int CHudScoreboard::Draw( float fTime ) int xpos = NAME_RANGE_MIN + xpos_rel; FAR_RIGHT = can_show_packetloss ? PL_RANGE_MAX : PING_RANGE_MAX; - FAR_RIGHT += 125; + FAR_RIGHT += 5; + + if( ( ScreenWidth >= 440 && !can_show_packetloss ) || ( ScreenWidth >= 520 && can_show_packetloss ) ) + { + xpos -= NAME_RANGE_MODIFIER; + FAR_RIGHT += NAME_RANGE_MODIFIER; + } + if( cl_scoreboard_bg && cl_scoreboard_bg->value ) gHUD.DrawDarkRectangle( xpos - 5, ypos - 5, FAR_RIGHT, ROW_RANGE_MAX ); if( !gHUD.m_Teamplay ) @@ -165,7 +173,7 @@ int CHudScoreboard::Draw( float fTime ) list_slot += 1.2; ypos = ROW_RANGE_MIN + ( list_slot * ROW_GAP ); - xpos = NAME_RANGE_MIN + xpos_rel; + // xpos = NAME_RANGE_MIN + xpos_rel; FillRGBA( xpos - 4, ypos, FAR_RIGHT -2, 1, 255, 140, 0, 255 ); // draw the seperator line list_slot += 0.8; @@ -266,12 +274,18 @@ int CHudScoreboard::Draw( float fTime ) break; xpos = NAME_RANGE_MIN + xpos_rel; + + if( ( ScreenWidth >= 440 && !can_show_packetloss ) || ( ScreenWidth >= 520 && can_show_packetloss ) ) + { + xpos -= NAME_RANGE_MODIFIER; + } + int r = 255, g = 225, b = 55; // draw the stuff kinda yellowish if( team_info->ownteam ) // if it is their team, draw the background different color { // overlay the background in blue, then draw the score text over it - FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, FAR_RIGHT, ROW_GAP, 0, 0, 255, 70 ); + FillRGBA( xpos - 5, ypos, FAR_RIGHT, ROW_GAP, 0, 0, 255, 70 ); } // draw their name (left to right) @@ -340,7 +354,12 @@ int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, } FAR_RIGHT = can_show_packetloss ? PL_RANGE_MAX : PING_RANGE_MAX; - FAR_RIGHT += 125; + FAR_RIGHT += 5; + + if( ( ScreenWidth >= 440 && !can_show_packetloss ) || ( ScreenWidth >= 520 && can_show_packetloss ) ) + { + FAR_RIGHT += NAME_RANGE_MODIFIER; + } // draw the players, in order, and restricted to team if set while( 1 ) @@ -380,6 +399,12 @@ int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, break; int xpos = NAME_RANGE_MIN + xpos_rel; + + if( ( ScreenWidth >= 440 && !can_show_packetloss ) || ( ScreenWidth >= 520 && can_show_packetloss ) ) + { + xpos -= NAME_RANGE_MODIFIER; + } + int r = 255, g = 255, b = 255; float *colors = GetClientColor( best_player ); r *= colors[0], g *= colors[1], b *= colors[2]; @@ -388,18 +413,18 @@ int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, if( pl_info->thisplayer ) { // green is the suicide color? i wish this could do grey... - FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, FAR_RIGHT, ROW_GAP, 80, 155, 0, 70 ); + FillRGBA( xpos - 5, ypos, FAR_RIGHT, ROW_GAP, 80, 155, 0, 70 ); } else { // Highlight the killers name - overlay the background in red, then draw the score text over it - FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, FAR_RIGHT, ROW_GAP, 255, 0, 0, ( (float)15 * (float)( m_fLastKillTime - gHUD.m_flTime ) ) ); + FillRGBA( xpos - 5, ypos, FAR_RIGHT, ROW_GAP, 255, 0, 0, ( (float)15 * (float)( m_fLastKillTime - gHUD.m_flTime ) ) ); } } else if( pl_info->thisplayer ) // if it is their name, draw it a different color { // overlay the background in blue, then draw the score text over it - FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, FAR_RIGHT, ROW_GAP, 0, 0, 255, 70 ); + FillRGBA( xpos - 5, ypos, FAR_RIGHT, ROW_GAP, 0, 0, 255, 70 ); } // draw their name (left to right) From f13adcfb8b7dc11d365389bc01ee3290f1d4ff26 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 15 Feb 2018 17:52:07 +0500 Subject: [PATCH 152/211] Fix infinite slide in multiplayer. --- pm_shared/pm_shared.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pm_shared/pm_shared.c b/pm_shared/pm_shared.c index 9aed8093..abe7b317 100644 --- a/pm_shared/pm_shared.c +++ b/pm_shared/pm_shared.c @@ -3312,8 +3312,8 @@ void PM_Move( struct playermove_s *ppmove, int server ) pmove->flags &= ~FL_ONGROUND; } - // In single player, reset friction after each movement to FrictionModifier Triggers work still. - if( !pmove->multiplayer && ( pmove->movetype == MOVETYPE_WALK ) ) + // Reset friction after each movement to FrictionModifier Triggers work still. + if( pmove->movetype == MOVETYPE_WALK ) { pmove->friction = 1.0f; } From 556e2647fe0ba801c75bf810e41ef58c5eb90c34 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Thu, 15 Feb 2018 18:15:02 +0500 Subject: [PATCH 153/211] Do not show train controls after player death. --- dlls/player.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dlls/player.cpp b/dlls/player.cpp index 52f5f546..99d4c7f6 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -782,6 +782,9 @@ void CBasePlayer::PackDeadPlayerItems( void ) void CBasePlayer::RemoveAllItems( BOOL removeSuit ) { + int i; + CBasePlayerItem *pPendingItem; + if( m_pActiveItem ) { ResetAutoaim(); @@ -794,8 +797,8 @@ void CBasePlayer::RemoveAllItems( BOOL removeSuit ) if( m_pTank != 0 ) m_pTank->Use( this, this, USE_OFF, 0 ); - int i; - CBasePlayerItem *pPendingItem; + m_iTrain = TRAIN_NEW; // turn off train + for( i = 0; i < MAX_ITEM_TYPES; i++ ) { m_pActiveItem = m_rgpPlayerItems[i]; From ccbc147c90bd530ef04af79a794fc6affb4c535e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sat, 3 Mar 2018 23:58:19 +0300 Subject: [PATCH 154/211] Fix Battery message spam when armorvalue goes fractional --- dlls/player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/player.cpp b/dlls/player.cpp index 99d4c7f6..bbd668ba 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -3935,7 +3935,7 @@ void CBasePlayer::UpdateClientData( void ) m_iClientHealth = (int)pev->health; } - if( pev->armorvalue != m_iClientBattery ) + if( (int)pev->armorvalue != m_iClientBattery ) { m_iClientBattery = (int)pev->armorvalue; From 4538ba1c19e0a3dd4898c3410ae751c821347b2e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sun, 4 Mar 2018 00:12:44 +0300 Subject: [PATCH 155/211] Force XP toolchain in newer Visual Studio --- CMakeLists.txt | 6 ++++++ cmake/VSForceXPToolchain.cmake | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 cmake/VSForceXPToolchain.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index e025342a..3403cfbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,12 @@ # cmake_minimum_required(VERSION 2.6.0) + +# Install custom module path +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") + +include(VSForceXPToolchain) # Force XP toolchain for Visual Studio + project (HLSDK-XASH3D) #-------------- diff --git a/cmake/VSForceXPToolchain.cmake b/cmake/VSForceXPToolchain.cmake new file mode 100644 index 00000000..e78fb0a2 --- /dev/null +++ b/cmake/VSForceXPToolchain.cmake @@ -0,0 +1,29 @@ +if(WIN32) + # Windows XP compatible platform toolset. Must be set before project(), + # otherwise change of CMAKE_*_TOOLSET will take no effect. + # We get VS version from the generator name because neither MSVC* nor other + # variables that describe the compiler aren't available before project(). + if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)") + if(${CMAKE_MATCH_1} LESS 11) + # Nothing. Older VS does support XP by default. + elseif(${CMAKE_MATCH_1} EQUAL 11) + # Visual Studio 11 2012 + set(CMAKE_GENERATOR_TOOLSET "v110_xp" CACHE STRING "CMAKE_GENERATOR_TOOLSET" FORCE) + set(CMAK_VS_PLATFORM_TOOLSET "v110_xp" CACHE STRING "CMAKE_VS_PLATFORM_TOOLSET" FORCE) + elseif (${CMAKE_MATCH_1} EQUAL 12) + # Visual Studio 12 2013 + set(CMAKE_GENERATOR_TOOLSET "v120_xp" CACHE STRING "CMAKE_GENERATOR_TOOLSET" FORCE) + set(CMAKE_VS_PLATFORM_TOOLSET "v120_xp" CACHE STRING "CMAKE_VS_PLATFORM_TOOLSET" FORCE) + elseif (${CMAKE_MATCH_1} EQUAL 14) + # Visual Studio 14 2015 + set(CMAKE_GENERATOR_TOOLSET "v140_xp" CACHE STRING "CMAKE_GENERATOR_TOOLSET" FORCE) + set(CMAKE_VS_PLATFORM_TOOLSET "v140_xp" CACHE STRING "CMAKE_VS_PLATFORM_TOOLSET" FORCE) + elseif (${CMAKE_MATCH_1} EQUAL 15) + # Visual Studio 15 2017 + set(CMAKE_GENERATOR_TOOLSET "v141_xp" CACHE STRING "CMAKE_GENERATOR_TOOLSET" FORCE) + set(CMAKE_VS_PLATFORM_TOOLSET "v141_xp" CACHE STRING "CMAKE_VS_PLATFORM_TOOLSET" FORCE) + else() + message(WARNING "WARNING: You maybe building without Windows XP compability. See which toolchain version Visual Studio provides, and say cmake to use it: cmake -G \"Visual Studio XX\" -T \"vXXX_xp\"") + endif() + endif() +endif() From 81d31cdbd19c7fb744c8fb981321bfcdedb1006b Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sun, 4 Mar 2018 00:13:52 +0300 Subject: [PATCH 156/211] Add appveyor --- appveyor.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..eb39ee2d --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,28 @@ +version: 1.0.{build} + +branches: + only: + - master + +environment: + matrix: + - os: Visual Studio 2013 + GENERATOR_NAME: "Visual Studio 12 2013" + - os: Visual Studio 2015 + GENERATOR_NAME: "Visual Studio 14 2015" +# TODO: Uncomment when AppVeyor will provide XP toolchain for VS2017 +# - os: Visual Studio 2017 +# GENERATOR_NAME: "Visual Studio 15 2017" + +clone_folder: c:\projects\xash\hlsdk-xash3d + +build: + project: INSTALL.vcxproj + verbosity: normal + +configuration: + - Debug + +before_build: + - git submodule update --init --recursive + - cmake -G "%GENERATOR_NAME%" From d52b03a9c465436dc78b012eca1677eeec8bad61 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sun, 4 Mar 2018 00:18:05 +0300 Subject: [PATCH 157/211] Add AppVeyor build status --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9261b1b3..a57d94b5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Half-Life SDK for Xash3D [![Build Status](https://travis-ci.org/FWGS/hlsdk-xash3d.svg)](https://travis-ci.org/FWGS/hlsdk-xash3d) +# Half-Life SDK for Xash3D [![Build Status](https://travis-ci.org/FWGS/hlsdk-xash3d.svg)](https://travis-ci.org/FWGS/hlsdk-xash3d) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/FWGS/hlsdk-xash3d?svg=true)](https://ci.appveyor.com/project/a1batross/hlsdk-xash3d) Half-Life SDK for Xash3D & GoldSource with some fixes. @@ -31,7 +31,7 @@ These scripts also can be ran via wine: The libraries built this way are always GoldSource compatible. -There're dsp projects for MVS 6 in `cl_dll` and `dlls` directories, but we don't keep them up-to-date. You're free to adapt them for yourself and try to import into the newer MVS versions. +There're dsp projects for Visual Studio 6 in `cl_dll` and `dlls` directories, but we don't keep them up-to-date. You're free to adapt them for yourself and try to import into the newer Visual Studio versions. #### Using mingw @@ -44,7 +44,7 @@ TODO ### OS X -TODO +Nothing here. ### FreeBSD From 6818ff091df1f4aae12ec784b5467bc4016e4f35 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sun, 4 Mar 2018 00:21:05 +0300 Subject: [PATCH 158/211] Remove cast pointer to size_t in cbase.h, it's useless here --- dlls/cbase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/cbase.h b/dlls/cbase.h index 4cf40abd..e200d7b0 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -283,7 +283,7 @@ public: #ifdef _DEBUG void FunctionCheck( void *pFunction, char *name ) { - if( pFunction && !NAME_FOR_FUNCTION( (size_t)( pFunction ) ) ) + if( pFunction && !NAME_FOR_FUNCTION( pFunction ) ) ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING( pev->classname ), name, (size_t)pFunction ); } From 6161c6d4d834f1eac22b1e16aad86ab5ecf6971b Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sun, 4 Mar 2018 00:24:54 +0300 Subject: [PATCH 159/211] Replace snprintf by _snprintf, for MSVC --- cl_dll/text_message.cpp | 8 ++++---- dlls/client.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cl_dll/text_message.cpp b/cl_dll/text_message.cpp index b959fc87..512623dd 100644 --- a/cl_dll/text_message.cpp +++ b/cl_dll/text_message.cpp @@ -181,20 +181,20 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf switch( msg_dest ) { case HUD_PRINTCENTER: - snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); + _snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); CenterPrint( ConvertCRtoNL( psz ) ); break; case HUD_PRINTNOTIFY: psz[0] = 1; // mark this message to go into the notify buffer - snprintf( psz + 1, MSG_BUF_SIZE - 1, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); + _snprintf( psz + 1, MSG_BUF_SIZE - 1, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); ConsolePrint( ConvertCRtoNL( psz ) ); break; case HUD_PRINTTALK: - snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); + _snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), MSG_BUF_SIZE ); break; case HUD_PRINTCONSOLE: - snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); + _snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); ConsolePrint( ConvertCRtoNL( psz ) ); break; } diff --git a/dlls/client.cpp b/dlls/client.cpp index 578534e3..1e7dab72 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -108,7 +108,7 @@ void ClientDisconnect( edict_t *pEntity ) char text[256] = ""; if( pEntity->v.netname ) - snprintf( text, sizeof(text), "- %s has left the game\n", STRING( pEntity->v.netname ) ); + _snprintf( text, sizeof(text), "- %s has left the game\n", STRING( pEntity->v.netname ) ); MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); WRITE_BYTE( ENTINDEX( pEntity ) ); WRITE_STRING( text ); @@ -660,7 +660,7 @@ void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) if( gpGlobals->maxClients > 1 ) { char text[256]; - snprintf( text, 256, "* %s changed name to %s\n", STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); + _snprintf( text, 256, "* %s changed name to %s\n", STRING( pEntity->v.netname ), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); WRITE_BYTE( ENTINDEX( pEntity ) ); WRITE_STRING( text ); From 4af903015604bbbbaf9b861fbd2e2b565520bcd1 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 22 Mar 2018 15:23:34 +0300 Subject: [PATCH 160/211] Append 64 postfix on 64 bit --- CMakeLists.txt | 3 ++- cl_dll/CMakeLists.txt | 7 ++++++- dlls/CMakeLists.txt | 7 ++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3403cfbd..705025bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ project (HLSDK-XASH3D) #-------------- # USER DEFINES \ ################\ +option(64BIT "Allow 64 Bit builds" OFF) option(USE_VGUI "Enable VGUI1. UNDONE" OFF) option(USE_VGUI2 "Enable VGUI2. UNDONE" OFF) option(USE_VOICEMGR "Enable VOICE MANAGER." OFF) @@ -50,7 +51,7 @@ set(SERVER_LIBRARY_NAME "hl" CACHE STRING "Library name for Linux/MacOS/Windows" set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") # Build 32-bit Xash on 64-bit, because Xash3D not support this -if(CMAKE_SIZEOF_VOID_P EQUAL 8) +if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT 64BIT) if(MSVC) error("UNDONE: set 32 build flags") else() diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 05990913..b848aa6c 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -125,8 +125,13 @@ set_target_properties (${CLDLL_LIBRARY} PROPERTIES POSITION_INDEPENDENT_CODE 1) if(APPLE OR WIN32 OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set(CLDLL_NAME "client") + if(64BIT) + set(CLDLL_NAME "client64") + endif() + set_target_properties(${CLDLL_LIBRARY} PROPERTIES - OUTPUT_NAME "client" + OUTPUT_NAME ${CLDLL_NAME} PREFIX "") endif() diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index bf7d3370..55370eeb 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -157,8 +157,13 @@ set_target_properties (${SVDLL_LIBRARY} PROPERTIES POSITION_INDEPENDENT_CODE 1) if(APPLE OR WIN32 OR ${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set(SVDLL_NAME "${SERVER_LIBRARY_NAME}") + if(64BIT) + set(SVDLL_NAME "${SERVER_LIBRARY_NAME}64") + endif() + set_target_properties(${SVDLL_LIBRARY} PROPERTIES - OUTPUT_NAME ${SERVER_LIBRARY_NAME} + OUTPUT_NAME ${SVDLL_NAME} PREFIX "") endif() From bc379e92343ae52d44c152baaf176e32f8ed9765 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 23 Mar 2018 23:08:38 +0300 Subject: [PATCH 161/211] Add 64/32 bit message and a dumb check when 32 bit isn't properly enabled --- CMakeLists.txt | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 705025bf..bd7fe664 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ option(USE_VOICEMGR "Enable VOICE MANAGER." OFF) option(BUILD_CLIENT "Build client dll" ON) option(BUILD_SERVER "Build server dll" ON) option(GOLDSOURCE_SUPPORT "Build goldsource compatible client library" OFF) +option(64BIT "Disable auto -m32 appending to compiler flags" OFF) set(GAMEDIR "valve" CACHE STRING "Gamedir path") set(SERVER_INSTALL_DIR "dlls" CACHE STRING "Where put server dll") set(CLIENT_INSTALL_DIR "cl_dlls" CACHE STRING "Where put client dll") @@ -50,25 +51,35 @@ set(SERVER_LIBRARY_NAME "hl" CACHE STRING "Library name for Linux/MacOS/Windows" set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") -# Build 32-bit Xash on 64-bit, because Xash3D not support this if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT 64BIT) if(MSVC) - error("UNDONE: set 32 build flags") + error("UNDONE: set 32 build flags") else() - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") endif() + set(CMAKE_SIZEOF_VOID_P 4) +endif() + +if(64BIT AND CMAKE_SIZEOF_VOID_P EQUAL 4) + message(FATAL_ERROR "You enabled XASH_64BIT, but compiler can't create 64 bit code!") +endif() + +if(64BIT) + message(STATUS "Building for 64 Bit") +else() + message(STATUS "Building for 32 Bit") endif() # add_compile_options for older cmake versions if(${CMAKE_VERSION} VERSION_LESS "3.0.2") -macro(add_compile_options) - set(list_var "${ARGV}") - foreach(arg IN LISTS list_var) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${arg}") - endforeach() -endmacro() + macro(add_compile_options) + set(list_var "${ARGV}") + foreach(arg IN LISTS list_var) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${arg}") + endforeach() + endmacro() endif() if(BUILD_CLIENT) From 3401f54148e4001b4aa893e92695b17d93b0b53e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 23 Mar 2018 23:46:05 +0300 Subject: [PATCH 162/211] Fix Android buil --- cl_dll/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl_dll/Android.mk b/cl_dll/Android.mk index 68917633..df6130ed 100755 --- a/cl_dll/Android.mk +++ b/cl_dll/Android.mk @@ -92,7 +92,7 @@ SRCS+=./input_xash3d.cpp SRCS+=./scoreboard.cpp SRCS+=./MOTD.cpp INCLUDES = -I../common -I. -I../game_shared -I../pm_shared -I../engine -I../dlls -I../utils/false_vgui/include -DEFINES = -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w +DEFINES = -Wno-write-strings -DLINUX -D_LINUX -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DCLIENT_WEAPONS -DCLIENT_DLL -w -D_snprintf=snprintf LOCAL_C_INCLUDES := $(LOCAL_PATH)/. \ $(LOCAL_PATH)/../common \ From 9d7ab6acf46a8b71ef119d9c252767865522d21d Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sat, 31 Mar 2018 17:09:13 +0500 Subject: [PATCH 163/211] Some fixes for FoV, HUD, egon flare and new compilers. (#52) * Fix warnings. * Merge some fixes from https://github.com/Fograin/hl-subs-mod. --- cl_dll/ev_hldm.cpp | 41 ++++++++++++++++++++++++++++++++++++- cl_dll/health.cpp | 3 ++- cl_dll/hl/hl_objects.cpp | 25 +++++++++++++++++++++- cl_dll/hl/hl_weapons.cpp | 2 ++ cl_dll/hud.cpp | 3 ++- cl_dll/hud.h | 2 +- cl_dll/hud_msg.cpp | 16 ++++++++++++++- cl_dll/input_goldsource.cpp | 2 +- cl_dll/scoreboard.cpp | 2 +- dlls/monsters.cpp | 3 ++- dlls/player.cpp | 18 +++++++++++++--- 11 files changed, 105 insertions(+), 12 deletions(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 628b5bfa..08127aa1 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -1414,6 +1414,17 @@ enum EGON_FIREMODE BEAM *pBeam; BEAM *pBeam2; +TEMPENTITY *pFlare; // Vit_amiN: egon's beam flare + +void EV_EgonFlareCallback( struct tempent_s *ent, float frametime, float currenttime ) +{ + float delta = currenttime - ent->tentOffset.z; // time past since the last scale + if( delta >= ent->tentOffset.y ) + { + ent->entity.curstate.scale += ent->tentOffset.x * delta; + ent->tentOffset.z = currenttime; + } +} void EV_EgonFire( event_args_t *args ) { @@ -1451,7 +1462,7 @@ void EV_EgonFire( event_args_t *args ) if( EV_IsLocal( idx ) ) gEngfuncs.pEventAPI->EV_WeaponAnimation( g_fireAnims1[gEngfuncs.pfnRandomLong( 0, 3 )], 1 ); - if( iStartup == 1 && EV_IsLocal( idx ) && !pBeam && !pBeam2 && cl_lw->value ) //Adrian: Added the cl_lw check for those lital people that hate weapon prediction. + if( iStartup == 1 && EV_IsLocal( idx ) && !( pBeam || pBeam2 || pFlare ) && cl_lw->value ) //Adrian: Added the cl_lw check for those lital people that hate weapon prediction. { vec3_t vecSrc, vecEnd, angles, forward, right, up; pmtrace_t tr; @@ -1499,8 +1510,16 @@ void EV_EgonFire( event_args_t *args ) pBeam->flags |= ( FBEAM_SINENOISE ); pBeam2 = gEngfuncs.pEfxAPI->R_BeamEntPoint( idx | 0x1000, tr.endpos, iBeamModelIndex, 99999, 5.0, 0.08, 0.7, 25, 0, 0, r, g, b ); + + // Vit_amiN: egon beam flare + pFlare = gEngfuncs.pEfxAPI->R_TempSprite( tr.endpos, vec3_origin, 1.0, gEngfuncs.pEventAPI->EV_FindModelIndex( EGON_FLARE_SPRITE ), kRenderGlow, kRenderFxNoDissipation, 1.0, 99999, FTENT_SPRCYCLE | FTENT_PERSIST ); } } + + if( pFlare ) // Vit_amiN: store the last mode for EV_EgonStop() + { + pFlare->tentOffset.x = ( iFireMode == FIRE_WIDE ) ? 1.0f : 0.0f; + } } void EV_EgonStop( event_args_t *args ) @@ -1529,6 +1548,26 @@ void EV_EgonStop( event_args_t *args ) pBeam2->die = 0.0; pBeam2 = NULL; } + + if( pFlare ) // Vit_amiN: egon beam flare + { + pFlare->die = gEngfuncs.GetClientTime(); + + if( gEngfuncs.GetMaxClients() == 1 || !(pFlare->flags & FTENT_NOMODEL) ) + { + if( pFlare->tentOffset.x != 0.0f ) // true for iFireMode == FIRE_WIDE + { + pFlare->callback = &EV_EgonFlareCallback; + pFlare->fadeSpeed = 2.0; // fade out will take 0.5 sec + pFlare->tentOffset.x = 10.0; // scaling speed per second + pFlare->tentOffset.y = 0.1; // min time between two scales + pFlare->tentOffset.z = pFlare->die; // the last callback run time + pFlare->flags = FTENT_FADEOUT | FTENT_CLIENTCUSTOM; + } + } + + pFlare = NULL; + } } } //====================== diff --git a/cl_dll/health.cpp b/cl_dll/health.cpp index d4979c35..eebf0eb0 100644 --- a/cl_dll/health.cpp +++ b/cl_dll/health.cpp @@ -231,7 +231,8 @@ int CHudHealth::Draw( float flTime ) int iHeight = gHUD.m_iFontHeight; int iWidth = HealthWidth / 10; - FillRGBA( x, y, iWidth, iHeight, 255, 160, 0, a ); + UnpackRGB( r, g, b, RGB_YELLOWISH ); + FillRGBA( x, y, iWidth, iHeight, r, g, b, a ); } DrawDamage( flTime ); diff --git a/cl_dll/hl/hl_objects.cpp b/cl_dll/hl/hl_objects.cpp index b51ee693..55822dcb 100644 --- a/cl_dll/hl/hl_objects.cpp +++ b/cl_dll/hl/hl_objects.cpp @@ -29,6 +29,7 @@ extern BEAM *pBeam; extern BEAM *pBeam2; +extern TEMPENTITY *pFlare; // Vit_amiN: egon's energy flare void HUD_GetLastOrg( float *org ); void UpdateBeams( void ) @@ -75,6 +76,28 @@ void UpdateBeams( void ) pBeam2->target = tr.endpos; pBeam2->die = gEngfuncs.GetClientTime() + 0.1; // We keep it alive just a little bit forward in the future, just in case. } + + if( pFlare ) // Vit_amiN: beam flare + { + pFlare->entity.origin = tr.endpos; + pFlare->die = gEngfuncs.GetClientTime() + 0.1; // We keep it alive just a little bit forward in the future, just in case. + + if( gEngfuncs.GetMaxClients() != 1 ) // Singleplayer always draws the egon's energy beam flare + { + pFlare->flags |= FTENT_NOMODEL; + + if( !( tr.allsolid || tr.ent <= 0 || tr.fraction == 1.0 ) ) // Beam hit some non-world entity + { + physent_t *pEntity = gEngfuncs.pEventAPI->EV_GetPhysent( tr.ent ); + + // Not the world, let's assume that we hit something organic ( dog, cat, uncle joe, etc ) + if( pEntity && !( pEntity->solid == SOLID_BSP || pEntity->movetype == MOVETYPE_PUSHSTEP ) ) + { + pFlare->flags &= ~FTENT_NOMODEL; + } + } + } + } } /* @@ -86,6 +109,6 @@ Add game specific, client-side objects here */ void Game_AddObjects( void ) { - if( pBeam && pBeam2 ) + if( pBeam || pBeam2 || pFlare ) // Vit_amiN: egon flare added UpdateBeams(); } diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 75161a9e..b2c1d7b3 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -34,6 +34,7 @@ extern globalvars_t *gpGlobals; extern int g_iUser1; +extern bool g_hasPredictedFOV; // Vit_amiN: from HUD // Pool of client side entities/entvars_t static entvars_t ev[32]; @@ -881,6 +882,7 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm to->client.fuser2 = player.m_flNextAmmoBurn; to->client.fuser3 = player.m_flAmmoStartCharge; to->client.maxspeed = player.pev->maxspeed; + g_hasPredictedFOV = true; // Vit_amiN: ready //HL Weapons to->client.vuser1[0] = player.ammo_9mm; diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 05bda284..195dfa5a 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -413,6 +413,7 @@ int CHud::MsgFunc_Logo( const char *pszName, int iSize, void *pbuf ) } float g_lastFOV = 0.0; +bool g_hasPredictedFOV = false; // Vit_amiN: it'll became true after the first prediction /* ============ @@ -514,7 +515,7 @@ int CHud::MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf ) int def_fov = CVAR_GET_FLOAT( "default_fov" ); //Weapon prediction already takes care of changing the fog. ( g_lastFOV ). - if( cl_lw && cl_lw->value ) + if( g_hasPredictedFOV ) return 1; g_lastFOV = newfov; diff --git a/cl_dll/hud.h b/cl_dll/hud.h index decfa917..f3e1ed85 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -230,7 +230,7 @@ public: void InitHUDData( void ); int VidInit( void ); int Draw( float flTime ); - int DrawPlayers( int xoffset, float listslot, int nameoffset = 0, char *team = NULL ); // returns the ypos where it finishes drawing + int DrawPlayers( int xoffset, float listslot, int nameoffset = 0, const char *team = NULL ); // returns the ypos where it finishes drawing void UserCmd_ShowScores( void ); void UserCmd_HideScores( void ); int MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf ); diff --git a/cl_dll/hud_msg.cpp b/cl_dll/hud_msg.cpp index 47f8bc92..b435a85c 100644 --- a/cl_dll/hud_msg.cpp +++ b/cl_dll/hud_msg.cpp @@ -25,6 +25,10 @@ extern BEAM *pBeam; extern BEAM *pBeam2; +extern TEMPENTITY *pFlare; // Vit_amiN + +extern float g_lastFOV; // Vit_amiN +extern bool g_hasPredictedFOV; // Vit_amiN /// USER-DEFINED SERVER MESSAGE HANDLERS @@ -48,6 +52,11 @@ int CHud::MsgFunc_ResetHUD( const char *pszName, int iSize, void *pbuf ) // reset concussion effect m_iConcussionEffect = 0; + // Vit_amiN: reset the FOV + m_iFOV = 0; // default_fov + g_lastFOV = 0.0f; + g_hasPredictedFOV = false; + return 1; } @@ -72,6 +81,7 @@ void CHud::MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf ) //Probably not a good place to put this. pBeam = pBeam2 = NULL; + pFlare = NULL; // Vit_amiN: clear egon's beam flare } int CHud::MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf ) @@ -107,10 +117,14 @@ int CHud::MsgFunc_Damage( const char *pszName, int iSize, void *pbuf ) int CHud::MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf ) { + int r, g, b; BEGIN_READ( pbuf, iSize ); m_iConcussionEffect = READ_BYTE(); if( m_iConcussionEffect ) - this->m_StatusIcons.EnableIcon( "dmg_concuss", 255, 160, 0 ); + { + UnpackRGB( r, g, b, RGB_YELLOWISH ); // Vit_amiN: fixed + this->m_StatusIcons.EnableIcon( "dmg_concuss", r, g, b ); + } else this->m_StatusIcons.DisableIcon( "dmg_concuss" ); return 1; diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index bd997784..c45841cb 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -1368,7 +1368,7 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd ) // y=ax^b; where a = 300 and b = 1.3 // also x values are in increments of 800 (so this is factored out) // then bounds check result to level out excessively high spin rates - fTemp = 300.0 * pow(abs(fAxisValue) / 800.0, 1.3); + fTemp = 300.0 * pow(fabs(fAxisValue) / 800.0, 1.3); if (fTemp > 14000.0) fTemp = 14000.0; // restore direction information diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index 0f26c6f2..5d52787c 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -337,7 +337,7 @@ int CHudScoreboard::Draw( float fTime ) extern float *GetClientColor( int client ); // returns the ypos where it finishes drawing -int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, char *team ) +int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, const char *team ) { int can_show_packetloss = 0; int FAR_RIGHT; diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index 1e1d3de3..953d1a69 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -2118,7 +2118,8 @@ void CBaseMonster::StartMonster( void ) SetThink( &CBaseMonster::CallMonsterThink ); pev->nextthink += RANDOM_FLOAT( 0.1, 0.4 ); // spread think times. - if( !FStringNull( pev->targetname ) )// wait until triggered + // Vit_amiN: fixed -- now it doesn't touch any scripted_sequence target + if( !FStringNull( pev->targetname ) && !m_pCine )// wait until triggered { SetState( MONSTERSTATE_IDLE ); // UNDONE: Some scripted sequence monsters don't have an idle? diff --git a/dlls/player.cpp b/dlls/player.cpp index bbd668ba..b1d28e67 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -1860,6 +1860,7 @@ void CBasePlayer::PreThink( void ) { CBaseEntity *pTrain = CBaseEntity::Instance( pev->groundentity ); float vel; + int iGearId; // Vit_amiN: keeps the train control HUD in sync if( !pTrain ) { @@ -1900,10 +1901,12 @@ void CBasePlayer::PreThink( void ) pTrain->Use( this, this, USE_SET, (float)vel ); } - if( vel ) + iGearId = TrainSpeed( pTrain->pev->speed, pTrain->pev->impulse ); + + if( iGearId != ( m_iTrain & 0x0F ) ) // Vit_amiN: speed changed { - m_iTrain = TrainSpeed( (int)pTrain->pev->speed, pTrain->pev->impulse ); - m_iTrain |= TRAIN_ACTIVE|TRAIN_NEW; + m_iTrain = iGearId; + m_iTrain |= TRAIN_ACTIVE | TRAIN_NEW; } } else if( m_iTrain & TRAIN_ACTIVE ) @@ -2919,6 +2922,8 @@ void CBasePlayer::Precache( void ) if( gInitHUD ) m_fInitHUD = TRUE; + + pev->fov = m_iFOV; // Vit_amiN: restore the FOV on level change or map/saved game load } int CBasePlayer::Save( CSave &save ) @@ -3326,6 +3331,8 @@ void CBasePlayer::ForceClientDllUpdate( void ) { m_iClientHealth = -1; m_iClientBattery = -1; + m_iClientHideHUD = -1; // Vit_amiN: forcing to update + m_iClientFOV = -1; // Vit_amiN: force client weapons to be sent m_iTrain |= TRAIN_NEW; // Force new train message. m_fWeapon = FALSE; // Force weapon send m_fKnownItem = FALSE; // Force weaponinit messages. @@ -3890,6 +3897,11 @@ void CBasePlayer::UpdateClientData( void ) WRITE_BYTE( m_iFlashBattery ); MESSAGE_END(); + // Vit_amiN: the geiger state could run out of sync, too + MESSAGE_BEGIN( MSG_ONE, gmsgGeigerRange, NULL, pev ); + WRITE_BYTE( 0 ); + MESSAGE_END(); + InitStatusBar(); } From f6ffc92d5d17c0d52ddceacff08193bd320b60a0 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sun, 1 Apr 2018 20:38:56 +0300 Subject: [PATCH 164/211] Always update gHUD.m_iFOV on SetFOV message. Fix #53 --- cl_dll/hl/hl_weapons.cpp | 2 -- cl_dll/hud.cpp | 5 ----- cl_dll/hud_msg.cpp | 2 -- 3 files changed, 9 deletions(-) diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index b2c1d7b3..75161a9e 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -34,7 +34,6 @@ extern globalvars_t *gpGlobals; extern int g_iUser1; -extern bool g_hasPredictedFOV; // Vit_amiN: from HUD // Pool of client side entities/entvars_t static entvars_t ev[32]; @@ -882,7 +881,6 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm to->client.fuser2 = player.m_flNextAmmoBurn; to->client.fuser3 = player.m_flAmmoStartCharge; to->client.maxspeed = player.pev->maxspeed; - g_hasPredictedFOV = true; // Vit_amiN: ready //HL Weapons to->client.vuser1[0] = player.ammo_9mm; diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 195dfa5a..3ef72889 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -413,7 +413,6 @@ int CHud::MsgFunc_Logo( const char *pszName, int iSize, void *pbuf ) } float g_lastFOV = 0.0; -bool g_hasPredictedFOV = false; // Vit_amiN: it'll became true after the first prediction /* ============ @@ -514,10 +513,6 @@ int CHud::MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf ) int newfov = READ_BYTE(); int def_fov = CVAR_GET_FLOAT( "default_fov" ); - //Weapon prediction already takes care of changing the fog. ( g_lastFOV ). - if( g_hasPredictedFOV ) - return 1; - g_lastFOV = newfov; if( newfov == 0 ) diff --git a/cl_dll/hud_msg.cpp b/cl_dll/hud_msg.cpp index b435a85c..7cc2fbad 100644 --- a/cl_dll/hud_msg.cpp +++ b/cl_dll/hud_msg.cpp @@ -28,7 +28,6 @@ extern BEAM *pBeam2; extern TEMPENTITY *pFlare; // Vit_amiN extern float g_lastFOV; // Vit_amiN -extern bool g_hasPredictedFOV; // Vit_amiN /// USER-DEFINED SERVER MESSAGE HANDLERS @@ -55,7 +54,6 @@ int CHud::MsgFunc_ResetHUD( const char *pszName, int iSize, void *pbuf ) // Vit_amiN: reset the FOV m_iFOV = 0; // default_fov g_lastFOV = 0.0f; - g_hasPredictedFOV = false; return 1; } From 0c515e34649dc7ce9e5be5fabfd71c61b0db04f0 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 2 Apr 2018 23:54:10 +0300 Subject: [PATCH 165/211] Update mobility interface --- engine/mobility_int.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/engine/mobility_int.h b/engine/mobility_int.h index 88f63315..d8b6120a 100644 --- a/engine/mobility_int.h +++ b/engine/mobility_int.h @@ -34,7 +34,7 @@ extern "C" { #define TOUCH_FL_DEF_HIDE (1U << 6) #define TOUCH_FL_DRAW_ADDITIVE (1U << 7) #define TOUCH_FL_STROKE (1U << 8) -#define TOUCH_FL_PRECISION (1U << 9) +#define TOUCH_FL_PRECISION (1U << 9) typedef struct mobile_engfuncs_s { @@ -65,13 +65,21 @@ typedef struct mobile_engfuncs_s void (*pfnTouchSetClientOnly)( unsigned char state ); // Clean defaults list - void (*pfnTouchResetDefaultButtons)(); + void (*pfnTouchResetDefaultButtons)( void ); + // Draw scaled font for client + int (*pfnDrawScaledCharacter)( int x, int y, int number, int r, int g, int b, float scale ); + + void (*pfnSys_Warn)( const char *format, ... ); + + // Get native object for current platform. + // Pass NULL to arguments to receive an array of available objects or NULL if nothing + void *(*pfnGetNativeObject)( const char *obj ); + + void (*pfnSetCustomClientID)( const char *id ); // To be continued... } mobile_engfuncs_t; -extern mobile_engfuncs_t *gMobileEngfuncs; - // function exported from client // returns 0 on no error otherwise error typedef int (*pfnMobilityInterface)( mobile_engfuncs_t *gMobileEngfuncs ); From cec6d7a1bc6383a81cdbb7622e6e4a1ec9ec1b07 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 2 Apr 2018 23:56:01 +0300 Subject: [PATCH 166/211] Add HUD_MessageBox. Rename isXashFWGS to IsXashFWGS --- cl_dll/cdll_int.cpp | 17 ++++++++++++++++- cl_dll/cl_util.h | 3 ++- cl_dll/hud_redraw.cpp | 2 +- cl_dll/input_mouse.cpp | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index fec09792..dc9199ba 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -376,7 +376,22 @@ void DLLEXPORT HUD_MobilityInterface( mobile_engfuncs_t *gpMobileEngfuncs ) gMobileEngfuncs = gpMobileEngfuncs; } -bool isXashFWGS() +bool HUD_MessageBox( const char *msg ) +{ + gEngfuncs.Con_Printf( msg ); // just in case + + if( IsXashFWGS() ) + { + gMobileEngfuncs->pfnSys_Warn( msg ); + return true; + } + + // TODO: Load SDL2 and call ShowSimpleMessageBox + + return false; +} + +bool IsXashFWGS() { return gMobileEngfuncs != NULL; } diff --git a/cl_dll/cl_util.h b/cl_dll/cl_util.h index 23f12230..0cb65f32 100644 --- a/cl_dll/cl_util.h +++ b/cl_dll/cl_util.h @@ -181,5 +181,6 @@ inline void UnpackRGB( int &r, int &g, int &b, unsigned long ulRGB )\ HSPRITE LoadSprite( const char *pszName ); -bool isXashFWGS(); +bool HUD_MessageBox( const char *msg ); +bool IsXashFWGS(); #endif diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index 06b25a33..4a46a519 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -235,7 +235,7 @@ int CHud::DrawHudString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int DrawUtfString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int g, int b ) { - if (isXashFWGS()) + if (IsXashFWGS()) { // xash3d: reset unicode state gEngfuncs.pfnVGUI2DrawCharacterAdditive( 0, 0, 0, 0, 0, 0, 0 ); diff --git a/cl_dll/input_mouse.cpp b/cl_dll/input_mouse.cpp index 8d57091b..3233d797 100644 --- a/cl_dll/input_mouse.cpp +++ b/cl_dll/input_mouse.cpp @@ -69,7 +69,7 @@ void IN_Shutdown( void ) void IN_Init( void ) { #ifdef SUPPORT_GOLDSOURCE_INPUT - if (isXashFWGS()) { + if (IsXashFWGS()) { gEngfuncs.Con_Printf( "FWGS Xash3D input is in use\n" ); currentInput = &fwgsInput; } else { From 6e5062b39e2118ccb967015265ce81df57dd1e08 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 2 Apr 2018 23:56:26 +0300 Subject: [PATCH 167/211] Check for bad game data(missing or invalid hud.txt) --- cl_dll/hud.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 3ef72889..62c32b41 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -381,6 +381,18 @@ void CHud::VidInit( void ) // assumption: number_1, number_2, etc, are all listed and loaded sequentially m_HUD_number_0 = GetSpriteIndex( "number_0" ); + if( m_HUD_number_0 == -1 ) + { + const char *msg = "There is something wrong with your game data! Please, reinstall\n"; + + if( HUD_MessageBox( msg ) ) + { + gEngfuncs.pfnClientCmd( "quit\n" ); + } + + return; + } + m_iFontHeight = m_rgrcRects[m_HUD_number_0].bottom - m_rgrcRects[m_HUD_number_0].top; m_Ammo.VidInit(); From 71f55bb119c7ec4d0c5dd6dc0c29dee5aa9bcda7 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Tue, 3 Apr 2018 21:39:07 +0300 Subject: [PATCH 168/211] Add mingw support to CMakeLists.txt. Add crosscompiling instructions to README.md --- CMakeLists.txt | 5 +++++ README.md | 8 ++++++++ cl_dll/CMakeLists.txt | 5 ++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd7fe664..64c48928 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,11 @@ else() message(STATUS "Building for 32 Bit") endif() +if (MINGW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--add-stdcall-alias") +endif() + # add_compile_options for older cmake versions if(${CMAKE_VERSION} VERSION_LESS "3.0.2") macro(add_compile_options) diff --git a/README.md b/README.md index a57d94b5..be0a5fa8 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ Half-Life SDK for Xash3D & GoldSource with some fixes. cmake ../ make +Crosscompiling using mingw: + + mkdir build-mingw && cd build-mingw + TOOLCHAIN_PREFIX=i686-w64-mingw32 # check up the actual mingw prefix of your mingw installation + cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER="$TOOLCHAIN_PREFIX-gcc" -DCMAKE_CXX_COMPILER="$TOOLCHAIN_PREFIX-g++" + You may enable or disable some build options by -Dkey=value. All available build options are defined in CMakeLists.txt at root directory. See below if you want to build the GoldSource compatible libraries. @@ -68,6 +74,8 @@ or when using make without cmake: Unlike original client by Valve the resulting client library will not depend on vgui or SDL2 just like the one that's used in FWGS Xash3d. +Note for **Windows**: it's not possible to create GoldSource compatible libraries using mingw, only msvc builds will work. + Note for **Linux**: GoldSource requires libraries (both client and server) to be compiled with libstdc++ bundled with g++ of major version 4 (versions from 4.6 to 4.9 should work). If your Linux distribution does not provide compatible g++ version you have several options. diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index b848aa6c..323d156f 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -32,7 +32,10 @@ if(NOT MSVC) add_compile_options(-fno-exceptions) # GCC/Clang flag add_compile_options(-Wno-write-strings) # GCC/Clang flag add_definitions(-D_LINUX -DLINUX) # It seems enough for all non-Win32 systems - add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf ) + add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp) + if(NOT MINGW) + add_definitions(-D_snprintf=snprintf -D_vsnprintf=vsnprintf) + endif() else() add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) endif() From d112f720ad305db4266fc39ed89add34d575ec92 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Tue, 3 Apr 2018 23:17:56 +0300 Subject: [PATCH 169/211] Test building with mingw on travis --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9e165b81..fecd6f5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,9 @@ os: sudo: true before_script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install gcc-multilib g++-multilib; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" && "CC" == "gcc" ]]; then sudo apt-get install mingw-w64-i686-dev binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686; fi script: - mkdir -p build && cd build - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=0 && make -j3 && rm -rf * - - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=1 && make -j3 && rm -rf * \ No newline at end of file + - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=1 && make -j3 && rm -rf * + - if [[ "$TRAVIS_OS_NAME" == "linux" && "CC" == "gcc" ]]; then cd ..; mkdir build-mingw; cd build-mingw; cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++; make -j3; fi From ec6afbe86d311a4679c282611efd53b0aea53d5a Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 4 Apr 2018 17:30:53 +0300 Subject: [PATCH 170/211] Fix addressing variables in travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fecd6f5b..01d2ba27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,9 @@ os: sudo: true before_script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install gcc-multilib g++-multilib; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" && "CC" == "gcc" ]]; then sudo apt-get install mingw-w64-i686-dev binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "gcc" ]]; then sudo apt-get install mingw-w64-i686-dev binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686; fi script: - mkdir -p build && cd build - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=0 && make -j3 && rm -rf * - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=1 && make -j3 && rm -rf * - - if [[ "$TRAVIS_OS_NAME" == "linux" && "CC" == "gcc" ]]; then cd ..; mkdir build-mingw; cd build-mingw; cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++; make -j3; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "gcc" ]]; then cd ..; mkdir build-mingw; cd build-mingw; cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ && make -j3; fi From d17387c61ffe0a81b2ae6c6737bc7f08d7040ab3 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sat, 7 Apr 2018 04:21:16 +0300 Subject: [PATCH 171/211] Some fixes for PM_InitTextureTypes() from ReGameDLL_CS --- pm_shared/pm_shared.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pm_shared/pm_shared.c b/pm_shared/pm_shared.c index abe7b317..ace56595 100644 --- a/pm_shared/pm_shared.c +++ b/pm_shared/pm_shared.c @@ -168,24 +168,23 @@ void PM_InitTextureTypes() char buffer[512]; int i, j; byte *pMemFile; - int fileSize, filePos; + int fileSize, filePos = 0; static qboolean bTextureTypeInit = false; if( bTextureTypeInit ) return; - memset(&( grgszTextureName[0][0] ), 0, CTEXTURESMAX * CBTEXTURENAMEMAX ); - memset( grgchTextureType, 0, CTEXTURESMAX ); + memset(&( grgszTextureName[0][0] ), 0, sizeof( grgszTextureName ) ); + memset( grgchTextureType, 0, sizeof( grgchTextureType ) ); gcTextures = 0; - fileSize = pmove->COM_FileSize( "sound/materials.txt" ); - pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, NULL ); + pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, &fileSize ); if( !pMemFile ) return; - memset( buffer, 0, 512 ); - filePos = 0; + memset( buffer, 0, sizeof( buffer ) ); + // for each line in the file... while( pmove->memfgets( pMemFile, fileSize, &filePos, buffer, 511 ) != NULL && (gcTextures < CTEXTURESMAX ) ) { From 3d7e2b0d933a5d27aed69f77e90f19e7c946728f Mon Sep 17 00:00:00 2001 From: Night Owl Date: Sun, 8 Apr 2018 03:25:13 +0500 Subject: [PATCH 172/211] Do not show flashlight sprite in spectator mode. --- cl_dll/flashlight.cpp | 3 +++ dlls/player.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cl_dll/flashlight.cpp b/cl_dll/flashlight.cpp index c3514c7d..ee3d6d22 100644 --- a/cl_dll/flashlight.cpp +++ b/cl_dll/flashlight.cpp @@ -108,6 +108,9 @@ int CHudFlashlight::Draw( float flTime ) int r, g, b, x, y, a; wrect_t rc; + if( gEngfuncs.IsSpectateOnly() ) + return 1; + if( !( gHUD.m_iWeaponBits & ( 1 << ( WEAPON_SUIT ) ) ) ) return 1; diff --git a/dlls/player.cpp b/dlls/player.cpp index b1d28e67..926bf1e1 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -1421,7 +1421,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) MESSAGE_END(); // Setup flags - m_iHideHUD = ( HIDEHUD_HEALTH | HIDEHUD_WEAPONS ); + m_iHideHUD = ( HIDEHUD_HEALTH | HIDEHUD_FLASHLIGHT | HIDEHUD_WEAPONS ); m_afPhysicsFlags |= PFLAG_OBSERVER; pev->effects = EF_NODRAW; pev->view_ofs = g_vecZero; From 75bc5105e786fef7ad865fee5226fbf88906541a Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sun, 8 Apr 2018 19:59:11 +0300 Subject: [PATCH 173/211] Remove old TEXTURETYPE code --- dlls/sound.cpp | 84 ++------------------------------------------------ dlls/world.cpp | 3 -- 2 files changed, 3 insertions(+), 84 deletions(-) diff --git a/dlls/sound.cpp b/dlls/sound.cpp index 31d0b7aa..30c44326 100644 --- a/dlls/sound.cpp +++ b/dlls/sound.cpp @@ -1454,14 +1454,6 @@ void EMIT_GROUPNAME_SUIT( edict_t *entity, const char *groupname ) // texture name to a material type. Play footstep sound based // on material type. -int fTextureTypeInit = FALSE; - -#define CTEXTURESMAX 512 // max number of textures loaded - -int gcTextures = 0; -char grgszTextureName[CTEXTURESMAX][CBTEXTURENAMEMAX]; // texture names -char grgchTextureType[CTEXTURESMAX]; // parallel array of texture types - // open materials.txt, get size, alloc space, // save in array. Only works first time called, // ignored on subsequent calls. @@ -1513,87 +1505,17 @@ static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer return NULL; } -void TEXTURETYPE_Init() -{ - char buffer[512]; - int i, j; - byte *pMemFile; - int fileSize, filePos = 0; - - if( fTextureTypeInit ) - return; - - memset( &( grgszTextureName[0][0] ), 0, CTEXTURESMAX * CBTEXTURENAMEMAX ); - memset( grgchTextureType, 0, CTEXTURESMAX ); - - gcTextures = 0; - - pMemFile = g_engfuncs.pfnLoadFileForMe( "sound/materials.txt", &fileSize ); - if( !pMemFile ) - return; - - memset( buffer, 0, 512 ); - // for each line in the file... - while( memfgets( pMemFile, fileSize, filePos, buffer, 511 ) != NULL && ( gcTextures < CTEXTURESMAX) ) - { - // skip whitespace - i = 0; - while( buffer[i] && isspace( buffer[i] ) ) - i++; - - if( !buffer[i] ) - continue; - - // skip comment lines - if( buffer[i] == '/' || !isalpha( buffer[i] ) ) - continue; - - // get texture type - grgchTextureType[gcTextures] = toupper( buffer[i++] ); - - // skip whitespace - while( buffer[i] && isspace( buffer[i] ) ) - i++; - - if( !buffer[i] ) - continue; - - // get sentence name - j = i; - while( buffer[j] && !isspace( buffer[j] ) ) - j++; - - if( !buffer[j] ) - continue; - - // null-terminate name and save in sentences array - j = Q_min( j, CBTEXTURENAMEMAX - 1 + i ); - buffer[j] = 0; - strcpy( &( grgszTextureName[gcTextures++][0] ), &( buffer[i] ) ); - } - - g_engfuncs.pfnFreeFile( pMemFile ); - - fTextureTypeInit = TRUE; -} - // given texture name, find texture type // if not found, return type 'concrete' // NOTE: this routine should ONLY be called if the // current texture under the player changes! +extern "C" char PM_FindTextureType( char *name ); + char TEXTURETYPE_Find( char *name ) { - // CONSIDER: pre-sort texture names and perform faster binary search here - - for( int i = 0; i < gcTextures; i++ ) - { - if( !strnicmp( name, &( grgszTextureName[i][0] ), CBTEXTURENAMEMAX - 1 ) ) - return grgchTextureType[i]; - } - - return CHAR_TEX_CONCRETE; + return PM_FindTextureType(name); } // play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the diff --git a/dlls/world.cpp b/dlls/world.cpp index 3b9a1f1e..ae5a41bc 100644 --- a/dlls/world.cpp +++ b/dlls/world.cpp @@ -500,9 +500,6 @@ void CWorld::Precache( void ) // ok to call this multiple times, calls after first are ignored. SENTENCEG_Init(); - // init texture type array from materials.txt - TEXTURETYPE_Init(); - // the area based ambient sounds MUST be the first precache_sounds // player precaches W_Precache(); // get weapon precaches From b63c1753a142e98598a86deac9e64276997261c8 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 11 Apr 2018 04:48:42 +0500 Subject: [PATCH 174/211] Do not break motd(Revert old changes). --- dlls/multiplay_gamerules.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 7922d413..de91ac6e 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -1650,8 +1650,8 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client ) { // read from the MOTD.txt file int length, char_count = 0; - const char *pFileList; - const char *aFileList = pFileList = (const char*)LOAD_FILE_FOR_ME( CVAR_GET_STRING( "motdfile" ), &length ); + char *pFileList; + char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( CVAR_GET_STRING( "motdfile" ), &length ); // send the server name MESSAGE_BEGIN( MSG_ONE, gmsgServerName, NULL, client ); @@ -1679,10 +1679,10 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client ) if( char_count < MAX_MOTD_LENGTH ) pFileList = aFileList + char_count; else - pFileList = 0; + *pFileList = 0; MESSAGE_BEGIN( MSG_ONE, gmsgMOTD, NULL, client ); - WRITE_BYTE( pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come + WRITE_BYTE( *pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come WRITE_STRING( chunk ); MESSAGE_END(); } From 352e52eb0d7eeb3b65191543297d594706456a52 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sun, 8 Jul 2018 15:49:23 +0300 Subject: [PATCH 175/211] Fix #62 ligthting issue. --- dlls/lights.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dlls/lights.cpp b/dlls/lights.cpp index 1c39266b..13e6d3a9 100644 --- a/dlls/lights.cpp +++ b/dlls/lights.cpp @@ -155,10 +155,10 @@ void CEnvLight::KeyValue( KeyValueData* pkvd ) } else if( j == 4 ) { - v /= 255; - r *= v; - g *= v; - b *= v; + float vf = v / 255.0f; + r *= vf; + g *= vf; + b *= vf; } // simulate qrad direct, ambient,and gamma adjustments, as well as engine scaling From 65cb1f54f467b225949fab42b75a10a4bd202466 Mon Sep 17 00:00:00 2001 From: Jonathan Poncelet Date: Tue, 7 Aug 2018 08:24:04 +0100 Subject: [PATCH 176/211] Made library functions hidden by default on Mac/Linux This resolves an issue where the server library was calling client library functions in error. --- cl_dll/CMakeLists.txt | 1 + dlls/CMakeLists.txt | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index 323d156f..1143eefe 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -31,6 +31,7 @@ add_definitions(-DCLIENT_WEAPONS -DCLIENT_DLL) if(NOT MSVC) add_compile_options(-fno-exceptions) # GCC/Clang flag add_compile_options(-Wno-write-strings) # GCC/Clang flag + add_compile_options(-fvisibility=hidden) # GCC/Clang flag add_definitions(-D_LINUX -DLINUX) # It seems enough for all non-Win32 systems add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp) if(NOT MINGW) diff --git a/dlls/CMakeLists.txt b/dlls/CMakeLists.txt index 55370eeb..ccaa0279 100644 --- a/dlls/CMakeLists.txt +++ b/dlls/CMakeLists.txt @@ -30,13 +30,14 @@ add_definitions(-DCLIENT_WEAPONS) if(NOT MSVC) add_compile_options(-fno-exceptions) # GCC/Clang flag add_compile_options(-Wno-invalid-offsetof) # GCC/Clang flag + add_compile_options(-fvisibility=hidden) # GCC/Clang flag add_definitions(-D_LINUX) # It seems enough for all non-Win32 systems add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf ) else() add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) endif() -set (SVDLL_SOURCES +set (SVDLL_SOURCES agrunt.cpp airtank.cpp aflock.cpp @@ -140,7 +141,7 @@ set (SVDLL_SOURCES ../pm_shared/pm_math.c ../pm_shared/pm_shared.c ) - + include_directories (. wpn_shared ../common ../engine ../pm_shared ../game_shared ../public) if(USE_VOICEMGR) From b423cac3de4336e47c7379d04652275c5a0bd7c8 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 12 Sep 2018 05:05:55 +0500 Subject: [PATCH 177/211] Use CMAKE_C_FLAGS value for C++ compilers. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 64c48928..918449e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,8 +55,8 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT 64BIT) if(MSVC) error("UNDONE: set 32 build flags") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") endif() set(CMAKE_SIZEOF_VOID_P 4) From 4dfdb6fc9891e95df952cbcd3bb60ee84951cd86 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 29 Nov 2018 15:22:17 +0300 Subject: [PATCH 178/211] Fix for goldsource running in fullscreen with resolution lower than screen's one (#67) --- cl_dll/cdll_int.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index dc9199ba..45bbcd67 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -212,7 +212,9 @@ void TeamFortressViewport::paintBackground() // int wide, tall; // getParent()->getSize( wide, tall ); // setSize( wide, tall ); - gEngfuncs.VGui_ViewportPaintBackground(HUD_GetRect()); + int extents[4]; + getParent()->getAbsExtents(extents[0],extents[1],extents[2],extents[3]); + gEngfuncs.VGui_ViewportPaintBackground(extents); } void *TeamFortressViewport::operator new( size_t stAllocateBlock ) From 60e15c98ee9e2edc01af7ea55599aceb40402732 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Mon, 3 Dec 2018 22:11:47 +0300 Subject: [PATCH 179/211] Enable camera rotation on death in Gold Source --- cl_dll/input_goldsource.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index c45841cb..25612592 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -161,6 +161,7 @@ bool isMouseRelative = false; extern globalvars_t *gpGlobals; #endif +int CL_IsDead( void ); extern Vector dead_viewangles; void V_StopPitchDrift( void ) @@ -823,7 +824,17 @@ void GoldSourceInput::IN_MouseMove ( float frametime, usercmd_t *cmd) int mx, my; vec3_t viewangles; - gEngfuncs.GetViewAngles( (float *)viewangles ); + if( gHUD.m_iIntermission ) + return; // we can't move during intermission + + if( CL_IsDead() ) + { + viewangles = dead_viewangles; // HACKHACK: see below + } + else + { + gEngfuncs.GetViewAngles( viewangles ); + } if ( in_mlook.state & 1) { @@ -880,8 +891,14 @@ void GoldSourceInput::IN_MouseMove ( float frametime, usercmd_t *cmd) } } - gEngfuncs.SetViewAngles( (float *)viewangles ); + // HACKHACK: change viewangles directly in viewcode, + // so viewangles when player is dead will not be changed on server + if( !CL_IsDead() ) + { + gEngfuncs.SetViewAngles( viewangles ); + } + dead_viewangles = viewangles; // keep them actual /* //#define TRACE_TEST #if defined( TRACE_TEST ) From 88992a82b8ffb33a1d3bb4e0dc8723c8c19e3da0 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Tue, 4 Dec 2018 07:06:30 +0300 Subject: [PATCH 180/211] Reformat spaces to tabs in input_goldsource.cpp --- cl_dll/input_goldsource.cpp | 1856 +++++++++++++++++------------------ 1 file changed, 928 insertions(+), 928 deletions(-) diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index 25612592..ae6d83e2 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -44,62 +44,62 @@ const char* (*pfnSDL_GameControllerName)(SDL_GameController*); int safe_pfnSDL_SetRelativeMouseMode(SDL_bool mode) { - if (pfnSDL_SetRelativeMouseMode) - return pfnSDL_SetRelativeMouseMode(mode); - return -1; + if (pfnSDL_SetRelativeMouseMode) + return pfnSDL_SetRelativeMouseMode(mode); + return -1; } Uint32 safe_pfnSDL_GetRelativeMouseState(int* x, int* y) { - if (pfnSDL_GetRelativeMouseState) - return pfnSDL_GetRelativeMouseState(x, y); - return 0; + if (pfnSDL_GetRelativeMouseState) + return pfnSDL_GetRelativeMouseState(x, y); + return 0; } int safe_pfnSDL_NumJoysticks() { - if (pfnSDL_NumJoysticks) - return pfnSDL_NumJoysticks(); - return -1; + if (pfnSDL_NumJoysticks) + return pfnSDL_NumJoysticks(); + return -1; } SDL_bool safe_pfnSDL_IsGameController(int joystick_index) { - if (pfnSDL_IsGameController) - return pfnSDL_IsGameController(joystick_index); - return SDL_FALSE; + if (pfnSDL_IsGameController) + return pfnSDL_IsGameController(joystick_index); + return SDL_FALSE; } SDL_GameController* safe_pfnSDL_GameControllerOpen(int joystick_index) { - if (pfnSDL_GameControllerOpen) - return pfnSDL_GameControllerOpen(joystick_index); - return NULL; + if (pfnSDL_GameControllerOpen) + return pfnSDL_GameControllerOpen(joystick_index); + return NULL; } Sint16 safe_pfnSDL_GameControllerGetAxis(SDL_GameController* gamecontroller, SDL_GameControllerAxis axis) { - if (pfnSDL_GameControllerGetAxis) - return pfnSDL_GameControllerGetAxis(gamecontroller, axis); - return 0; + if (pfnSDL_GameControllerGetAxis) + return pfnSDL_GameControllerGetAxis(gamecontroller, axis); + return 0; } Uint8 safe_pfnSDL_GameControllerGetButton(SDL_GameController* gamecontroller, SDL_GameControllerButton button) { - if (pfnSDL_GameControllerGetButton) - return pfnSDL_GameControllerGetButton(gamecontroller, button); - return 0; + if (pfnSDL_GameControllerGetButton) + return pfnSDL_GameControllerGetButton(gamecontroller, button); + return 0; } void safe_pfnSDL_JoystickUpdate() { - if (pfnSDL_JoystickUpdate) - pfnSDL_JoystickUpdate(); + if (pfnSDL_JoystickUpdate) + pfnSDL_JoystickUpdate(); } const char* safe_pfnSDL_GameControllerName(SDL_GameController* gamecontroller) { - if (pfnSDL_GameControllerName) - return pfnSDL_GameControllerName(gamecontroller); - return NULL; + if (pfnSDL_GameControllerName) + return pfnSDL_GameControllerName(gamecontroller); + return NULL; } struct SDLFunction { - void** ppfnFunc; - const char* name; + void** ppfnFunc; + const char* name; }; static SDLFunction sdlFunctions[] = { {(void**)&pfnSDL_SetRelativeMouseMode, "SDL_SetRelativeMouseMode"}, @@ -129,15 +129,15 @@ extern cl_enginefunc_t gEngfuncs; extern int iMouseInUse; -extern kbutton_t in_strafe; -extern kbutton_t in_mlook; -extern kbutton_t in_speed; -extern kbutton_t in_jlook; +extern kbutton_t in_strafe; +extern kbutton_t in_mlook; +extern kbutton_t in_speed; +extern kbutton_t in_jlook; -extern cvar_t *m_pitch; -extern cvar_t *m_yaw; -extern cvar_t *m_forward; -extern cvar_t *m_side; +extern cvar_t *m_pitch; +extern cvar_t *m_yaw; +extern cvar_t *m_forward; +extern cvar_t *m_side; extern cvar_t *lookstrafe; extern cvar_t *lookspring; @@ -170,8 +170,8 @@ void V_StopPitchDrift( void ) } // mouse variables -cvar_t *m_filter; -extern cvar_t *sensitivity; +cvar_t *m_filter; +extern cvar_t *sensitivity; // Custom mouse acceleration (0 disable, 1 to enable, 2 enable with separate yaw/pitch rescale) static cvar_t *m_customaccel; @@ -189,44 +189,44 @@ static cvar_t *m_customaccel_exponent; static cvar_t *m_mousethread_sleep; #endif -float mouse_x, mouse_y; +float mouse_x, mouse_y; -static int restore_spi; -static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; -static int mouseactive = 0; -static int mouseparmsvalid; -static int mouseshowtoggle = 1; +static int restore_spi; +static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; +static int mouseactive = 0; +static int mouseparmsvalid; +static int mouseshowtoggle = 1; // joystick defines and variables // where should defines be moved? -#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick -#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball -#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V -#define JOY_AXIS_X 0 -#define JOY_AXIS_Y 1 -#define JOY_AXIS_Z 2 -#define JOY_AXIS_R 3 -#define JOY_AXIS_U 4 -#define JOY_AXIS_V 5 +#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick +#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball +#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V +#define JOY_AXIS_X 0 +#define JOY_AXIS_Y 1 +#define JOY_AXIS_Z 2 +#define JOY_AXIS_R 3 +#define JOY_AXIS_U 4 +#define JOY_AXIS_V 5 enum _ControlList { - AxisNada = 0, - AxisForward, - AxisLook, - AxisSide, - AxisTurn + AxisNada = 0, + AxisForward, + AxisLook, + AxisSide, + AxisTurn }; #if !defined(USE_SDL2) && defined(_WIN32) DWORD dwAxisFlags[JOY_MAX_AXES] = { - JOY_RETURNX, - JOY_RETURNY, - JOY_RETURNZ, - JOY_RETURNR, - JOY_RETURNU, - JOY_RETURNV + JOY_RETURNX, + JOY_RETURNY, + JOY_RETURNZ, + JOY_RETURNR, + JOY_RETURNU, + JOY_RETURNV }; #endif @@ -237,10 +237,10 @@ int pdwRawValue[ JOY_MAX_AXES ]; #elif defined(_WIN32) PDWORD pdwRawValue[ JOY_MAX_AXES ]; #endif -DWORD joy_oldbuttonstate, joy_oldpovstate; +DWORD joy_oldbuttonstate, joy_oldpovstate; -int joy_id; -DWORD joy_numbuttons; +int joy_id; +DWORD joy_numbuttons; #ifdef USE_SDL2 SDL_GameController *s_pJoystick = NULL; @@ -274,13 +274,13 @@ cvar_t *joy_yawsensitivity; cvar_t *joy_wwhack1; cvar_t *joy_wwhack2; -int joy_avail, joy_advancedinit, joy_haspov; +int joy_avail, joy_advancedinit, joy_haspov; #ifdef _WIN32 unsigned int s_hMouseThreadId = 0; -HANDLE s_hMouseThread = 0; -HANDLE s_hMouseQuitEvent = 0; -HANDLE s_hMouseThreadActiveLock = 0; +HANDLE s_hMouseThread = 0; +HANDLE s_hMouseQuitEvent = 0; +HANDLE s_hMouseThreadActiveLock = 0; #endif /* @@ -290,14 +290,14 @@ Force_CenterView_f */ void Force_CenterView_f (void) { - vec3_t viewangles; + vec3_t viewangles; - if (!iMouseInUse) - { - gEngfuncs.GetViewAngles( (float *)viewangles ); - viewangles[PITCH] = 0; - gEngfuncs.SetViewAngles( (float *)viewangles ); - } + if (!iMouseInUse) + { + gEngfuncs.GetViewAngles( (float *)viewangles ); + viewangles[PITCH] = 0; + gEngfuncs.SetViewAngles( (float *)viewangles ); + } } #ifdef _WIN32 @@ -311,129 +311,129 @@ LONG mouseThreadSleep = 0; bool MouseThread_ActiveLock_Enter( void ) { - if(!m_bMouseThread) - return true; + if(!m_bMouseThread) + return true; - return WAIT_OBJECT_0 == WaitForSingleObject( s_hMouseThreadActiveLock, INFINITE); + return WAIT_OBJECT_0 == WaitForSingleObject( s_hMouseThreadActiveLock, INFINITE); } void MouseThread_ActiveLock_Exit( void ) { - if(!m_bMouseThread) - return; + if(!m_bMouseThread) + return; - SetEvent( s_hMouseThreadActiveLock ); + SetEvent( s_hMouseThreadActiveLock ); } unsigned __stdcall MouseThread_Function( void * pArg ) { - while ( true ) - { - DWORD sleepVal = (DWORD)InterlockedExchangeAdd(&mouseThreadSleep, 0); - if(0 > sleepVal) sleepVal = 0; - else if(1000 < sleepVal) sleepVal = 1000; - if(WAIT_OBJECT_0 == WaitForSingleObject( s_hMouseQuitEvent, sleepVal)) - { - break; - } + while ( true ) + { + DWORD sleepVal = (DWORD)InterlockedExchangeAdd(&mouseThreadSleep, 0); + if(0 > sleepVal) sleepVal = 0; + else if(1000 < sleepVal) sleepVal = 1000; + if(WAIT_OBJECT_0 == WaitForSingleObject( s_hMouseQuitEvent, sleepVal)) + { + break; + } - if( MouseThread_ActiveLock_Enter() ) - { - if ( InterlockedExchangeAdd(&mouseThreadActive, 0) ) - { - POINT mouse_pos; - POINT center_pos; + if( MouseThread_ActiveLock_Enter() ) + { + if ( InterlockedExchangeAdd(&mouseThreadActive, 0) ) + { + POINT mouse_pos; + POINT center_pos; - center_pos.x = InterlockedExchangeAdd(&mouseThreadCenterX, 0); - center_pos.y = InterlockedExchangeAdd(&mouseThreadCenterY, 0); - GetCursorPos(&mouse_pos); + center_pos.x = InterlockedExchangeAdd(&mouseThreadCenterX, 0); + center_pos.y = InterlockedExchangeAdd(&mouseThreadCenterY, 0); + GetCursorPos(&mouse_pos); - mouse_pos.x -= center_pos.x; - mouse_pos.y -= center_pos.y; + mouse_pos.x -= center_pos.x; + mouse_pos.y -= center_pos.y; - if(mouse_pos.x || mouse_pos.y) SetCursorPos( center_pos.x, center_pos.y ); + if(mouse_pos.x || mouse_pos.y) SetCursorPos( center_pos.x, center_pos.y ); - InterlockedExchangeAdd(&mouseThreadDeltaX, mouse_pos.x); - InterlockedExchangeAdd(&mouseThreadDeltaY, mouse_pos.y); - } + InterlockedExchangeAdd(&mouseThreadDeltaX, mouse_pos.x); + InterlockedExchangeAdd(&mouseThreadDeltaY, mouse_pos.y); + } - MouseThread_ActiveLock_Exit(); - } - } + MouseThread_ActiveLock_Exit(); + } + } - return 0; + return 0; } /// Updates mouseThreadActive using the global variables mouseactive, iVisibleMouse and m_bRawInput. Should be called after any of these is changed. /// Has to be interlocked manually by programmer! Use MouseThread_ActiveLock_Enter and MouseThread_ActiveLock_Exit. void UpdateMouseThreadActive(void) { - InterlockedExchange(&mouseThreadActive, mouseactive && !iVisibleMouse && !m_bRawInput); + InterlockedExchange(&mouseThreadActive, mouseactive && !iVisibleMouse && !m_bRawInput); } #endif void IN_SetMouseMode(bool enable) { - static bool currentMouseMode = false; + static bool currentMouseMode = false; - if(enable == currentMouseMode) - return; + if(enable == currentMouseMode) + return; - if(enable) - { + if(enable) + { #ifdef _WIN32 - if (mouseparmsvalid) - restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); + if (mouseparmsvalid) + restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); - m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; - if(m_bRawInput) - { + m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; + if(m_bRawInput) + { #ifdef USE_SDL2 - safe_pfnSDL_SetRelativeMouseMode(SDL_TRUE); + safe_pfnSDL_SetRelativeMouseMode(SDL_TRUE); #endif - isMouseRelative = true; - } + isMouseRelative = true; + } #else - safe_pfnSDL_SetRelativeMouseMode(SDL_TRUE); + safe_pfnSDL_SetRelativeMouseMode(SDL_TRUE); #endif - currentMouseMode = true; - } - else - { + currentMouseMode = true; + } + else + { #ifdef _WIN32 - if(isMouseRelative) - { + if(isMouseRelative) + { #ifdef USE_SDL2 - safe_pfnSDL_SetRelativeMouseMode(SDL_FALSE); + safe_pfnSDL_SetRelativeMouseMode(SDL_FALSE); #endif - isMouseRelative = false; - } + isMouseRelative = false; + } - if (restore_spi) - SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); + if (restore_spi) + SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); #else - safe_pfnSDL_SetRelativeMouseMode(SDL_FALSE); + safe_pfnSDL_SetRelativeMouseMode(SDL_FALSE); #endif - currentMouseMode = false; - } + currentMouseMode = false; + } } void IN_SetVisibleMouse(bool visible) { #ifdef _WIN32 - bool lockEntered = MouseThread_ActiveLock_Enter(); + bool lockEntered = MouseThread_ActiveLock_Enter(); #endif - iVisibleMouse = visible; + iVisibleMouse = visible; - IN_SetMouseMode(!visible); + IN_SetMouseMode(!visible); #ifdef _WIN32 - UpdateMouseThreadActive(); - if(lockEntered) MouseThread_ActiveLock_Exit(); + UpdateMouseThreadActive(); + if(lockEntered) MouseThread_ActiveLock_Exit(); #endif } @@ -446,24 +446,24 @@ IN_ActivateMouse */ void GoldSourceInput::IN_ActivateMouse (void) { - if (mouseinitialized) - { + if (mouseinitialized) + { #ifdef _WIN32 - bool lockEntered = MouseThread_ActiveLock_Enter(); + bool lockEntered = MouseThread_ActiveLock_Enter(); #endif - IN_SetMouseMode(true); + IN_SetMouseMode(true); - mouseactive = 1; + mouseactive = 1; #ifdef _WIN32 - UpdateMouseThreadActive(); - if(lockEntered) MouseThread_ActiveLock_Exit(); + UpdateMouseThreadActive(); + if(lockEntered) MouseThread_ActiveLock_Exit(); #endif - // now is a good time to reset mouse positon: - IN_ResetMouse(); - } + // now is a good time to reset mouse positon: + IN_ResetMouse(); + } } @@ -474,21 +474,21 @@ IN_DeactivateMouse */ void GoldSourceInput::IN_DeactivateMouse (void) { - if (mouseinitialized) - { + if (mouseinitialized) + { #ifdef _WIN32 - bool lockEntered = MouseThread_ActiveLock_Enter(); + bool lockEntered = MouseThread_ActiveLock_Enter(); #endif - IN_SetMouseMode(false); + IN_SetMouseMode(false); - mouseactive = 0; + mouseactive = 0; #ifdef _WIN32 - UpdateMouseThreadActive(); - if(lockEntered) MouseThread_ActiveLock_Exit(); + UpdateMouseThreadActive(); + if(lockEntered) MouseThread_ActiveLock_Exit(); #endif - } + } } /* @@ -498,34 +498,34 @@ IN_StartupMouse */ void GoldSourceInput::IN_StartupMouse (void) { - if ( gEngfuncs.CheckParm ("-nomouse", NULL ) ) - return; + if ( gEngfuncs.CheckParm ("-nomouse", NULL ) ) + return; - mouseinitialized = 1; + mouseinitialized = 1; #ifdef _WIN32 - mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); + mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); - if (mouseparmsvalid) - { - if ( gEngfuncs.CheckParm ("-noforcemspd", NULL ) ) - newmouseparms[2] = originalmouseparms[2]; + if (mouseparmsvalid) + { + if ( gEngfuncs.CheckParm ("-noforcemspd", NULL ) ) + newmouseparms[2] = originalmouseparms[2]; - if ( gEngfuncs.CheckParm ("-noforcemaccel", NULL ) ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - } + if ( gEngfuncs.CheckParm ("-noforcemaccel", NULL ) ) + { + newmouseparms[0] = originalmouseparms[0]; + newmouseparms[1] = originalmouseparms[1]; + } - if ( gEngfuncs.CheckParm ("-noforcemparms", NULL ) ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - newmouseparms[2] = originalmouseparms[2]; - } - } + if ( gEngfuncs.CheckParm ("-noforcemparms", NULL ) ) + { + newmouseparms[0] = originalmouseparms[0]; + newmouseparms[1] = originalmouseparms[1]; + newmouseparms[2] = originalmouseparms[2]; + } + } #endif - mouse_buttons = MOUSE_BUTTON_COUNT; + mouse_buttons = MOUSE_BUTTON_COUNT; } /* @@ -535,43 +535,43 @@ IN_Shutdown */ void GoldSourceInput::IN_Shutdown (void) { - IN_DeactivateMouse (); + IN_DeactivateMouse (); #ifdef _WIN32 - if ( s_hMouseQuitEvent ) - { - SetEvent( s_hMouseQuitEvent ); - } + if ( s_hMouseQuitEvent ) + { + SetEvent( s_hMouseQuitEvent ); + } - if ( s_hMouseThread ) - { - if(WAIT_OBJECT_0 != WaitForSingleObject( s_hMouseThread, 5000 )) - { - TerminateThread( s_hMouseThread, 0 ); - } - CloseHandle( s_hMouseThread ); - s_hMouseThread = (HANDLE)0; - } + if ( s_hMouseThread ) + { + if(WAIT_OBJECT_0 != WaitForSingleObject( s_hMouseThread, 5000 )) + { + TerminateThread( s_hMouseThread, 0 ); + } + CloseHandle( s_hMouseThread ); + s_hMouseThread = (HANDLE)0; + } - if ( s_hMouseQuitEvent ) - { - CloseHandle( s_hMouseQuitEvent ); - s_hMouseQuitEvent = (HANDLE)0; - } + if ( s_hMouseQuitEvent ) + { + CloseHandle( s_hMouseQuitEvent ); + s_hMouseQuitEvent = (HANDLE)0; + } - if( s_hMouseThreadActiveLock ) - { - CloseHandle( s_hMouseThreadActiveLock ); - s_hMouseThreadActiveLock = (HANDLE)0; - } + if( s_hMouseThreadActiveLock ) + { + CloseHandle( s_hMouseThreadActiveLock ); + s_hMouseThreadActiveLock = (HANDLE)0; + } #endif #ifdef USE_SDL2 - for (int j=0; jvalue; + // This is the default sensitivity + float mouse_senstivity = ( gHUD.GetSensitivity() != 0 ) ? gHUD.GetSensitivity() : sensitivity->value; - // Using special accleration values - if ( m_customaccel->value != 0 ) - { - float raw_mouse_movement_distance = sqrt( mx * mx + my * my ); - float acceleration_scale = m_customaccel_scale->value; - float accelerated_sensitivity_max = m_customaccel_max->value; - float accelerated_sensitivity_exponent = m_customaccel_exponent->value; - float accelerated_sensitivity = ( (float)pow( raw_mouse_movement_distance, accelerated_sensitivity_exponent ) * acceleration_scale + mouse_senstivity ); + // Using special accleration values + if ( m_customaccel->value != 0 ) + { + float raw_mouse_movement_distance = sqrt( mx * mx + my * my ); + float acceleration_scale = m_customaccel_scale->value; + float accelerated_sensitivity_max = m_customaccel_max->value; + float accelerated_sensitivity_exponent = m_customaccel_exponent->value; + float accelerated_sensitivity = ( (float)pow( raw_mouse_movement_distance, accelerated_sensitivity_exponent ) * acceleration_scale + mouse_senstivity ); - if ( accelerated_sensitivity_max > 0.0001f && - accelerated_sensitivity > accelerated_sensitivity_max ) - { - accelerated_sensitivity = accelerated_sensitivity_max; - } + if ( accelerated_sensitivity_max > 0.0001f && + accelerated_sensitivity > accelerated_sensitivity_max ) + { + accelerated_sensitivity = accelerated_sensitivity_max; + } - *x *= accelerated_sensitivity; - *y *= accelerated_sensitivity; + *x *= accelerated_sensitivity; + *y *= accelerated_sensitivity; - // Further re-scale by yaw and pitch magnitude if user requests alternate mode 2 - // This means that they will need to up their value for m_customaccel_scale greatly (>40x) since m_pitch/yaw default - // to 0.022 - if ( m_customaccel->value == 2 ) - { - *x *= m_yaw->value; - *y *= m_pitch->value; - } - } - else - { - // Just apply the default - *x *= mouse_senstivity; - *y *= mouse_senstivity; - } + // Further re-scale by yaw and pitch magnitude if user requests alternate mode 2 + // This means that they will need to up their value for m_customaccel_scale greatly (>40x) since m_pitch/yaw default + // to 0.022 + if ( m_customaccel->value == 2 ) + { + *x *= m_yaw->value; + *y *= m_pitch->value; + } + } + else + { + // Just apply the default + *x *= mouse_senstivity; + *y *= mouse_senstivity; + } } void GoldSourceInput::IN_GetMouseDelta( int *pOutX, int *pOutY) { - bool active = mouseactive && !iVisibleMouse; - int mx, my; + bool active = mouseactive && !iVisibleMouse; + int mx, my; - if(active) - { - int deltaX, deltaY; + if(active) + { + int deltaX, deltaY; #ifdef _WIN32 - if ( !m_bRawInput ) - { - if ( m_bMouseThread ) - { - // update mouseThreadSleep: - InterlockedExchange(&mouseThreadSleep, (LONG)m_mousethread_sleep->value); + if ( !m_bRawInput ) + { + if ( m_bMouseThread ) + { + // update mouseThreadSleep: + InterlockedExchange(&mouseThreadSleep, (LONG)m_mousethread_sleep->value); - bool lockEntered = MouseThread_ActiveLock_Enter(); + bool lockEntered = MouseThread_ActiveLock_Enter(); - current_pos.x = InterlockedExchange( &mouseThreadDeltaX, 0 ); - current_pos.y = InterlockedExchange( &mouseThreadDeltaY, 0 ); + current_pos.x = InterlockedExchange( &mouseThreadDeltaX, 0 ); + current_pos.y = InterlockedExchange( &mouseThreadDeltaY, 0 ); - if(lockEntered) MouseThread_ActiveLock_Exit(); - } - else - { - GetCursorPos (¤t_pos); - } - } - else + if(lockEntered) MouseThread_ActiveLock_Exit(); + } + else + { + GetCursorPos (¤t_pos); + } + } + else #endif - { + { #ifdef USE_SDL2 - safe_pfnSDL_GetRelativeMouseState( &deltaX, &deltaY ); - current_pos.x = deltaX; - current_pos.y = deltaY; + safe_pfnSDL_GetRelativeMouseState( &deltaX, &deltaY ); + current_pos.x = deltaX; + current_pos.y = deltaY; #else - GetCursorPos (¤t_pos); - deltaX = current_pos.x - gEngfuncs.GetWindowCenterX(); - deltaY = current_pos.y - gEngfuncs.GetWindowCenterY(); + GetCursorPos (¤t_pos); + deltaX = current_pos.x - gEngfuncs.GetWindowCenterX(); + deltaY = current_pos.y - gEngfuncs.GetWindowCenterY(); #endif - } + } #ifdef _WIN32 - if ( !m_bRawInput ) - { - if ( m_bMouseThread ) - { - mx = current_pos.x; - my = current_pos.y; - } - else - { - mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum; - my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum; - } - } - else + if ( !m_bRawInput ) + { + if ( m_bMouseThread ) + { + mx = current_pos.x; + my = current_pos.y; + } + else + { + mx = current_pos.x - gEngfuncs.GetWindowCenterX() + mx_accum; + my = current_pos.y - gEngfuncs.GetWindowCenterY() + my_accum; + } + } + else #endif - { - mx = deltaX + mx_accum; - my = deltaY + my_accum; - } + { + mx = deltaX + mx_accum; + my = deltaY + my_accum; + } - mx_accum = 0; - my_accum = 0; + mx_accum = 0; + my_accum = 0; - // reset mouse position if required, so there is room to move: + // reset mouse position if required, so there is room to move: #ifdef _WIN32 - // do not reset if mousethread would do it: - if ( m_bRawInput || !m_bMouseThread ) + // do not reset if mousethread would do it: + if ( m_bRawInput || !m_bMouseThread ) #else - if(true) + if(true) #endif - IN_ResetMouse(); + IN_ResetMouse(); #ifdef _WIN32 - // update m_bRawInput occasionally: - if ( gpGlobals && gpGlobals->time - s_flRawInputUpdateTime > 1.0f ) - { - s_flRawInputUpdateTime = gpGlobals->time; + // update m_bRawInput occasionally: + if ( gpGlobals && gpGlobals->time - s_flRawInputUpdateTime > 1.0f ) + { + s_flRawInputUpdateTime = gpGlobals->time; - bool lockEntered = MouseThread_ActiveLock_Enter(); + bool lockEntered = MouseThread_ActiveLock_Enter(); - m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; + m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; - if(m_bRawInput && !isMouseRelative) - { + if(m_bRawInput && !isMouseRelative) + { #ifdef USE_SDL2 - safe_pfnSDL_SetRelativeMouseMode(SDL_TRUE); + safe_pfnSDL_SetRelativeMouseMode(SDL_TRUE); #endif - isMouseRelative = true; - } - else if(!m_bRawInput && isMouseRelative) - { + isMouseRelative = true; + } + else if(!m_bRawInput && isMouseRelative) + { #ifdef USE_SDL2 - safe_pfnSDL_SetRelativeMouseMode(SDL_FALSE); + safe_pfnSDL_SetRelativeMouseMode(SDL_FALSE); #endif - isMouseRelative = false; - } + isMouseRelative = false; + } - UpdateMouseThreadActive(); - if(lockEntered) MouseThread_ActiveLock_Exit(); - } + UpdateMouseThreadActive(); + if(lockEntered) MouseThread_ActiveLock_Exit(); + } #endif - } - else - { - mx = my = 0; - } + } + else + { + mx = my = 0; + } - if(pOutX) *pOutX = mx; - if(pOutY) *pOutY = my; + if(pOutX) *pOutX = mx; + if(pOutY) *pOutY = my; } /* @@ -821,8 +821,8 @@ IN_MouseMove */ void GoldSourceInput::IN_MouseMove ( float frametime, usercmd_t *cmd) { - int mx, my; - vec3_t viewangles; + int mx, my; + vec3_t viewangles; if( gHUD.m_iIntermission ) return; // we can't move during intermission @@ -836,60 +836,60 @@ void GoldSourceInput::IN_MouseMove ( float frametime, usercmd_t *cmd) gEngfuncs.GetViewAngles( viewangles ); } - if ( in_mlook.state & 1) - { - V_StopPitchDrift (); - } + if ( in_mlook.state & 1) + { + V_StopPitchDrift (); + } - //jjb - this disbles normal mouse control if the user is trying to - // move the camera, or if the mouse cursor is visible or if we're in intermission - if ( !iMouseInUse && !gHUD.m_iIntermission && !iVisibleMouse ) - { - IN_GetMouseDelta( &mx, &my ); + //jjb - this disbles normal mouse control if the user is trying to + // move the camera, or if the mouse cursor is visible or if we're in intermission + if ( !iMouseInUse && !gHUD.m_iIntermission && !iVisibleMouse ) + { + IN_GetMouseDelta( &mx, &my ); - if (m_filter && m_filter->value) - { - mouse_x = (mx + old_mouse_x) * 0.5; - mouse_y = (my + old_mouse_y) * 0.5; - } - else - { - mouse_x = mx; - mouse_y = my; - } + if (m_filter && m_filter->value) + { + mouse_x = (mx + old_mouse_x) * 0.5; + mouse_y = (my + old_mouse_y) * 0.5; + } + else + { + mouse_x = mx; + mouse_y = my; + } - old_mouse_x = mx; - old_mouse_y = my; + old_mouse_x = mx; + old_mouse_y = my; - // Apply custom mouse scaling/acceleration - IN_ScaleMouse( &mouse_x, &mouse_y ); + // Apply custom mouse scaling/acceleration + IN_ScaleMouse( &mouse_x, &mouse_y ); - // add mouse X/Y movement to cmd - if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) )) - cmd->sidemove += m_side->value * mouse_x; - else - viewangles[YAW] -= m_yaw->value * mouse_x; + // add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) )) + cmd->sidemove += m_side->value * mouse_x; + else + viewangles[YAW] -= m_yaw->value * mouse_x; - if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) - { - viewangles[PITCH] += m_pitch->value * mouse_y; - if (viewangles[PITCH] > cl_pitchdown->value) - viewangles[PITCH] = cl_pitchdown->value; - if (viewangles[PITCH] < -cl_pitchup->value) - viewangles[PITCH] = -cl_pitchup->value; - } - else - { - if ((in_strafe.state & 1) && gEngfuncs.IsNoClipping() ) - { - cmd->upmove -= m_forward->value * mouse_y; - } - else - { - cmd->forwardmove -= m_forward->value * mouse_y; - } - } - } + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + viewangles[PITCH] += m_pitch->value * mouse_y; + if (viewangles[PITCH] > cl_pitchdown->value) + viewangles[PITCH] = cl_pitchdown->value; + if (viewangles[PITCH] < -cl_pitchup->value) + viewangles[PITCH] = -cl_pitchup->value; + } + else + { + if ((in_strafe.state & 1) && gEngfuncs.IsNoClipping() ) + { + cmd->upmove -= m_forward->value * mouse_y; + } + else + { + cmd->forwardmove -= m_forward->value * mouse_y; + } + } + } // HACKHACK: change viewangles directly in viewcode, // so viewangles when player is dead will not be changed on server @@ -902,12 +902,12 @@ void GoldSourceInput::IN_MouseMove ( float frametime, usercmd_t *cmd) /* //#define TRACE_TEST #if defined( TRACE_TEST ) - { - int mx, my; - void V_Move( int mx, int my ); - IN_GetMousePos( &mx, &my ); - V_Move( mx, my ); - } + { + int mx, my; + void V_Move( int mx, int my ); + IN_GetMousePos( &mx, &my ); + V_Move( mx, my ); + } #endif */ } @@ -919,49 +919,49 @@ IN_Accumulate */ void GoldSourceInput::IN_Accumulate (void) { - //only accumulate mouse if we are not moving the camera with the mouse - if ( !iMouseInUse && !iVisibleMouse) - { - if (mouseactive) - { + //only accumulate mouse if we are not moving the camera with the mouse + if ( !iMouseInUse && !iVisibleMouse) + { + if (mouseactive) + { #ifdef _WIN32 - if ( !m_bRawInput ) - { - if ( !m_bMouseThread ) - { - GetCursorPos (¤t_pos); + if ( !m_bRawInput ) + { + if ( !m_bMouseThread ) + { + GetCursorPos (¤t_pos); - mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); - my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); - } - } - else + mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); + my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); + } + } + else #endif - { + { #ifdef USE_SDL2 - int deltaX, deltaY; - safe_pfnSDL_GetRelativeMouseState( &deltaX, &deltaY ); - mx_accum += deltaX; - my_accum += deltaY; + int deltaX, deltaY; + safe_pfnSDL_GetRelativeMouseState( &deltaX, &deltaY ); + mx_accum += deltaX; + my_accum += deltaY; #else - GetCursorPos (¤t_pos); + GetCursorPos (¤t_pos); - mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); - my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); + mx_accum += current_pos.x - gEngfuncs.GetWindowCenterX(); + my_accum += current_pos.y - gEngfuncs.GetWindowCenterY(); #endif - } + } - // force the mouse to the center, so there's room to move + // force the mouse to the center, so there's room to move #ifdef _WIN32 - // do not reset if mousethread would do it: - if ( m_bRawInput || !m_bMouseThread ) + // do not reset if mousethread would do it: + if ( m_bRawInput || !m_bMouseThread ) #else - if(true) + if(true) #endif - IN_ResetMouse(); + IN_ResetMouse(); - } - } + } + } } @@ -972,12 +972,12 @@ IN_ClearStates */ void GoldSourceInput::IN_ClearStates (void) { - if ( !mouseactive ) - return; + if ( !mouseactive ) + return; - mx_accum = 0; - my_accum = 0; - mouse_oldbuttonstate = 0; + mx_accum = 0; + my_accum = 0; + mouse_oldbuttonstate = 0; } /* @@ -987,136 +987,136 @@ IN_StartupJoystick */ void IN_StartupJoystick (void) { - // abort startup if user requests no joystick - if ( gEngfuncs.CheckParm ("-nojoy", NULL ) ) - return; + // abort startup if user requests no joystick + if ( gEngfuncs.CheckParm ("-nojoy", NULL ) ) + return; - // assume no joystick - joy_avail = 0; + // assume no joystick + joy_avail = 0; #ifdef USE_SDL2 - int nJoysticks = safe_pfnSDL_NumJoysticks(); - if ( nJoysticks > 0 ) - { - for ( int i = 0; i < nJoysticks; i++ ) - { - if ( safe_pfnSDL_IsGameController( i ) ) - { - s_pJoystick = safe_pfnSDL_GameControllerOpen( i ); - if ( s_pJoystick ) - { - //save the joystick's number of buttons and POV status - joy_numbuttons = SDL_CONTROLLER_BUTTON_MAX; - joy_haspov = 0; + int nJoysticks = safe_pfnSDL_NumJoysticks(); + if ( nJoysticks > 0 ) + { + for ( int i = 0; i < nJoysticks; i++ ) + { + if ( safe_pfnSDL_IsGameController( i ) ) + { + s_pJoystick = safe_pfnSDL_GameControllerOpen( i ); + if ( s_pJoystick ) + { + //save the joystick's number of buttons and POV status + joy_numbuttons = SDL_CONTROLLER_BUTTON_MAX; + joy_haspov = 0; - // old button and POV states default to no buttons pressed - joy_oldbuttonstate = joy_oldpovstate = 0; + // old button and POV states default to no buttons pressed + joy_oldbuttonstate = joy_oldpovstate = 0; - // mark the joystick as available and advanced initialization not completed - // this is needed as cvars are not available during initialization - gEngfuncs.Con_Printf ("joystick found\n\n", safe_pfnSDL_GameControllerName(s_pJoystick)); - joy_avail = 1; - joy_advancedinit = 0; - break; - } - } - } - } - else - { - gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); - } + // mark the joystick as available and advanced initialization not completed + // this is needed as cvars are not available during initialization + gEngfuncs.Con_Printf ("joystick found\n\n", safe_pfnSDL_GameControllerName(s_pJoystick)); + joy_avail = 1; + joy_advancedinit = 0; + break; + } + } + } + } + else + { + gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); + } #elif defined(_WIN32) - int numdevs; - JOYCAPS jc; - MMRESULT mmr; - // verify joystick driver is present - if ((numdevs = joyGetNumDevs ()) == 0) - { - gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); - return; - } + int numdevs; + JOYCAPS jc; + MMRESULT mmr; + // verify joystick driver is present + if ((numdevs = joyGetNumDevs ()) == 0) + { + gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); + return; + } - // cycle through the joystick ids for the first valid one - for (joy_id=0 ; joy_idvalue == 0.0) - { - // default joystick initialization - // 2 axes only with joystick control - dwAxisMap[JOY_AXIS_X] = AxisTurn; - // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; - dwAxisMap[JOY_AXIS_Y] = AxisForward; - // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; - } - else - { - if ( strcmp ( joy_name->string, "joystick") != 0 ) - { - // notify user of advanced controller - gEngfuncs.Con_Printf ("\n%s configured\n\n", joy_name->string); - } + if( joy_advanced->value == 0.0) + { + // default joystick initialization + // 2 axes only with joystick control + dwAxisMap[JOY_AXIS_X] = AxisTurn; + // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; + dwAxisMap[JOY_AXIS_Y] = AxisForward; + // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; + } + else + { + if ( strcmp ( joy_name->string, "joystick") != 0 ) + { + // notify user of advanced controller + gEngfuncs.Con_Printf ("\n%s configured\n\n", joy_name->string); + } - // advanced initialization here - // data supplied by user via joy_axisn cvars - dwTemp = (DWORD) joy_advaxisx->value; - dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisy->value; - dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisz->value; - dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisr->value; - dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisu->value; - dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisv->value; - dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; - } + // advanced initialization here + // data supplied by user via joy_axisn cvars + dwTemp = (DWORD) joy_advaxisx->value; + dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisy->value; + dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisz->value; + dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisr->value; + dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisu->value; + dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; + dwTemp = (DWORD) joy_advaxisv->value; + dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; + dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; + } #if !defined(USE_SDL2) && defined(_WIN32) - // compute the axes to collect from DirectInput - joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV; - for (i = 0; i < JOY_MAX_AXES; i++) - { - if (dwAxisMap[i] != AxisNada) - { - joy_flags |= dwAxisFlags[i]; - } - } + // compute the axes to collect from DirectInput + joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV; + for (i = 0; i < JOY_MAX_AXES; i++) + { + if (dwAxisMap[i] != AxisNada) + { + joy_flags |= dwAxisFlags[i]; + } + } #endif } @@ -1201,85 +1201,85 @@ IN_Commands */ void GoldSourceInput::IN_Commands (void) { - int i, key_index; + int i, key_index; - if (!joy_avail) - { - return; - } + if (!joy_avail) + { + return; + } - DWORD buttonstate, povstate; + DWORD buttonstate, povstate; - // loop through the joystick buttons - // key a joystick event or auxillary event for higher number buttons for each state change + // loop through the joystick buttons + // key a joystick event or auxillary event for higher number buttons for each state change #ifdef USE_SDL2 - buttonstate = 0; - for ( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) - { - if ( safe_pfnSDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) ) - { - buttonstate |= 1<value != 0.0) - { - ji.dwUpos += 100; - } - return 1; - } - else - { - // read error occurred - // turning off the joystick seems too harsh for 1 read error,\ - // but what should be done? - // Con_Printf ("IN_ReadJoystick: no response\n"); - // joy_avail = 0; - return 0; - } + if (joyGetPosEx (joy_id, &ji) == JOYERR_NOERROR) + { + // this is a hack -- there is a bug in the Logitech WingMan Warrior DirectInput Driver + // rather than having 32768 be the zero point, they have the zero point at 32668 + // go figure -- anyway, now we get the full resolution out of the device + if (joy_wwhack1->value != 0.0) + { + ji.dwUpos += 100; + } + return 1; + } + else + { + // read error occurred + // turning off the joystick seems too harsh for 1 read error,\ + // but what should be done? + // Con_Printf ("IN_ReadJoystick: no response\n"); + // joy_avail = 0; + return 0; + } #else - return 0; + return 0; #endif } @@ -1331,189 +1331,189 @@ IN_JoyMove */ void IN_JoyMove ( float frametime, usercmd_t *cmd ) { - float speed, aspeed; - float fAxisValue, fTemp; - int i; - vec3_t viewangles; + float speed, aspeed; + float fAxisValue, fTemp; + int i; + vec3_t viewangles; - gEngfuncs.GetViewAngles( (float *)viewangles ); + gEngfuncs.GetViewAngles( (float *)viewangles ); - // complete initialization if first time in - // this is needed as cvars are not available at initialization time - if( joy_advancedinit != 1 ) - { - Joy_AdvancedUpdate_f(); - joy_advancedinit = 1; - } + // complete initialization if first time in + // this is needed as cvars are not available at initialization time + if( joy_advancedinit != 1 ) + { + Joy_AdvancedUpdate_f(); + joy_advancedinit = 1; + } - // verify joystick is available and that the user wants to use it - if (!joy_avail || !in_joystick->value) - { - return; - } + // verify joystick is available and that the user wants to use it + if (!joy_avail || !in_joystick->value) + { + return; + } - // collect the joystick data, if possible - if (IN_ReadJoystick () != 1) - { - return; - } + // collect the joystick data, if possible + if (IN_ReadJoystick () != 1) + { + return; + } - if (in_speed.state & 1) - speed = cl_movespeedkey->value; - else - speed = 1; + if (in_speed.state & 1) + speed = cl_movespeedkey->value; + else + speed = 1; - aspeed = speed * frametime; + aspeed = speed * frametime; - // loop through the axes - for (i = 0; i < JOY_MAX_AXES; i++) - { - // get the floating point zero-centered, potentially-inverted data for the current axis + // loop through the axes + for (i = 0; i < JOY_MAX_AXES; i++) + { + // get the floating point zero-centered, potentially-inverted data for the current axis #ifdef USE_SDL2 - fAxisValue = (float)pdwRawValue[i]; + fAxisValue = (float)pdwRawValue[i]; #elif defined(_WIN32) - fAxisValue = (float) *pdwRawValue[i]; - fAxisValue -= 32768.0; + fAxisValue = (float) *pdwRawValue[i]; + fAxisValue -= 32768.0; #endif - if (joy_wwhack2->value != 0.0) - { - if (dwAxisMap[i] == AxisTurn) - { - // this is a special formula for the Logitech WingMan Warrior - // y=ax^b; where a = 300 and b = 1.3 - // also x values are in increments of 800 (so this is factored out) - // then bounds check result to level out excessively high spin rates - fTemp = 300.0 * pow(fabs(fAxisValue) / 800.0, 1.3); - if (fTemp > 14000.0) - fTemp = 14000.0; - // restore direction information - fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp; - } - } + if (joy_wwhack2->value != 0.0) + { + if (dwAxisMap[i] == AxisTurn) + { + // this is a special formula for the Logitech WingMan Warrior + // y=ax^b; where a = 300 and b = 1.3 + // also x values are in increments of 800 (so this is factored out) + // then bounds check result to level out excessively high spin rates + fTemp = 300.0 * pow(fabs(fAxisValue) / 800.0, 1.3); + if (fTemp > 14000.0) + fTemp = 14000.0; + // restore direction information + fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp; + } + } - // convert range from -32768..32767 to -1..1 - fAxisValue /= 32768.0; + // convert range from -32768..32767 to -1..1 + fAxisValue /= 32768.0; - switch (dwAxisMap[i]) - { - case AxisForward: - if ((joy_advanced->value == 0.0) && (in_jlook.state & 1)) - { - // user wants forward control to become look control - if (fabs(fAxisValue) > joy_pitchthreshold->value) - { - // if mouse invert is on, invert the joystick pitch value - // only absolute control support here (joy_advanced is 0) - if (m_pitch->value < 0.0) - { - viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - else - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - V_StopPitchDrift(); - } - else - { - // no pitch movement - // disable pitch return-to-center unless requested by user - // *** this code can be removed when the lookspring bug is fixed - // *** the bug always has the lookspring feature on - if(lookspring->value == 0.0) - { - V_StopPitchDrift(); - } - } - } - else - { - // user wants forward control to be forward control - if (fabs(fAxisValue) > joy_forwardthreshold->value) - { - cmd->forwardmove += (fAxisValue * joy_forwardsensitivity->value) * speed * cl_forwardspeed->value; - } - } - break; + switch (dwAxisMap[i]) + { + case AxisForward: + if ((joy_advanced->value == 0.0) && (in_jlook.state & 1)) + { + // user wants forward control to become look control + if (fabs(fAxisValue) > joy_pitchthreshold->value) + { + // if mouse invert is on, invert the joystick pitch value + // only absolute control support here (joy_advanced is 0) + if (m_pitch->value < 0.0) + { + viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; + } + else + { + viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; + } + V_StopPitchDrift(); + } + else + { + // no pitch movement + // disable pitch return-to-center unless requested by user + // *** this code can be removed when the lookspring bug is fixed + // *** the bug always has the lookspring feature on + if(lookspring->value == 0.0) + { + V_StopPitchDrift(); + } + } + } + else + { + // user wants forward control to be forward control + if (fabs(fAxisValue) > joy_forwardthreshold->value) + { + cmd->forwardmove += (fAxisValue * joy_forwardsensitivity->value) * speed * cl_forwardspeed->value; + } + } + break; - case AxisSide: - if (fabs(fAxisValue) > joy_sidethreshold->value) - { - cmd->sidemove += (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; - } - break; + case AxisSide: + if (fabs(fAxisValue) > joy_sidethreshold->value) + { + cmd->sidemove += (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; + } + break; - case AxisTurn: - if ((in_strafe.state & 1) || (lookstrafe->value && (in_jlook.state & 1))) - { - // user wants turn control to become side control - if (fabs(fAxisValue) > joy_sidethreshold->value) - { - cmd->sidemove -= (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; - } - } - else - { - // user wants turn control to be turn control - if (fabs(fAxisValue) > joy_yawthreshold->value) - { - if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) - { - viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * aspeed * cl_yawspeed->value; - } - else - { - viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * speed * 180.0; - } + case AxisTurn: + if ((in_strafe.state & 1) || (lookstrafe->value && (in_jlook.state & 1))) + { + // user wants turn control to become side control + if (fabs(fAxisValue) > joy_sidethreshold->value) + { + cmd->sidemove -= (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; + } + } + else + { + // user wants turn control to be turn control + if (fabs(fAxisValue) > joy_yawthreshold->value) + { + if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) + { + viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * aspeed * cl_yawspeed->value; + } + else + { + viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * speed * 180.0; + } - } - } - break; + } + } + break; - case AxisLook: - if (in_jlook.state & 1) - { - if (fabs(fAxisValue) > joy_pitchthreshold->value) - { - // pitch movement detected and pitch movement desired by user - if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - else - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * speed * 180.0; - } - V_StopPitchDrift(); - } - else - { - // no pitch movement - // disable pitch return-to-center unless requested by user - // *** this code can be removed when the lookspring bug is fixed - // *** the bug always has the lookspring feature on - if( lookspring->value == 0.0 ) - { - V_StopPitchDrift(); - } - } - } - break; + case AxisLook: + if (in_jlook.state & 1) + { + if (fabs(fAxisValue) > joy_pitchthreshold->value) + { + // pitch movement detected and pitch movement desired by user + if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) + { + viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; + } + else + { + viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * speed * 180.0; + } + V_StopPitchDrift(); + } + else + { + // no pitch movement + // disable pitch return-to-center unless requested by user + // *** this code can be removed when the lookspring bug is fixed + // *** the bug always has the lookspring feature on + if( lookspring->value == 0.0 ) + { + V_StopPitchDrift(); + } + } + } + break; - default: - break; - } - } + default: + break; + } + } - // bounds check pitch - if (viewangles[PITCH] > cl_pitchdown->value) - viewangles[PITCH] = cl_pitchdown->value; - if (viewangles[PITCH] < -cl_pitchup->value) - viewangles[PITCH] = -cl_pitchup->value; + // bounds check pitch + if (viewangles[PITCH] > cl_pitchdown->value) + viewangles[PITCH] = cl_pitchdown->value; + if (viewangles[PITCH] < -cl_pitchup->value) + viewangles[PITCH] = -cl_pitchup->value; - gEngfuncs.SetViewAngles( (float *)viewangles ); + gEngfuncs.SetViewAngles( (float *)viewangles ); } /* @@ -1523,12 +1523,12 @@ IN_Move */ void GoldSourceInput::IN_Move ( float frametime, usercmd_t *cmd) { - if ( !iMouseInUse && mouseactive ) - { - IN_MouseMove ( frametime, cmd); - } + if ( !iMouseInUse && mouseactive ) + { + IN_MouseMove ( frametime, cmd); + } - IN_JoyMove ( frametime, cmd); + IN_JoyMove ( frametime, cmd); } /* @@ -1538,62 +1538,62 @@ IN_Init */ void GoldSourceInput::IN_Init (void) { - m_filter = gEngfuncs.pfnRegisterVariable ( "m_filter","0", FCVAR_ARCHIVE ); - sensitivity = gEngfuncs.pfnRegisterVariable ( "sensitivity","3", FCVAR_ARCHIVE ); // user mouse sensitivity setting. + m_filter = gEngfuncs.pfnRegisterVariable ( "m_filter","0", FCVAR_ARCHIVE ); + sensitivity = gEngfuncs.pfnRegisterVariable ( "sensitivity","3", FCVAR_ARCHIVE ); // user mouse sensitivity setting. - in_joystick = gEngfuncs.pfnRegisterVariable ( "joystick","0", FCVAR_ARCHIVE ); - joy_name = gEngfuncs.pfnRegisterVariable ( "joyname", "joystick", 0 ); - joy_advanced = gEngfuncs.pfnRegisterVariable ( "joyadvanced", "0", 0 ); - joy_advaxisx = gEngfuncs.pfnRegisterVariable ( "joyadvaxisx", "0", 0 ); - joy_advaxisy = gEngfuncs.pfnRegisterVariable ( "joyadvaxisy", "0", 0 ); - joy_advaxisz = gEngfuncs.pfnRegisterVariable ( "joyadvaxisz", "0", 0 ); - joy_advaxisr = gEngfuncs.pfnRegisterVariable ( "joyadvaxisr", "0", 0 ); - joy_advaxisu = gEngfuncs.pfnRegisterVariable ( "joyadvaxisu", "0", 0 ); - joy_advaxisv = gEngfuncs.pfnRegisterVariable ( "joyadvaxisv", "0", 0 ); - joy_forwardthreshold = gEngfuncs.pfnRegisterVariable ( "joyforwardthreshold", "0.15", 0 ); - joy_sidethreshold = gEngfuncs.pfnRegisterVariable ( "joysidethreshold", "0.15", 0 ); - joy_pitchthreshold = gEngfuncs.pfnRegisterVariable ( "joypitchthreshold", "0.15", 0 ); - joy_yawthreshold = gEngfuncs.pfnRegisterVariable ( "joyyawthreshold", "0.15", 0 ); - joy_forwardsensitivity = gEngfuncs.pfnRegisterVariable ( "joyforwardsensitivity", "-1.0", 0 ); - joy_sidesensitivity = gEngfuncs.pfnRegisterVariable ( "joysidesensitivity", "-1.0", 0 ); - joy_pitchsensitivity = gEngfuncs.pfnRegisterVariable ( "joypitchsensitivity", "1.0", 0 ); - joy_yawsensitivity = gEngfuncs.pfnRegisterVariable ( "joyyawsensitivity", "-1.0", 0 ); - joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 ); - joy_wwhack2 = gEngfuncs.pfnRegisterVariable ( "joywwhack2", "0.0", 0 ); + in_joystick = gEngfuncs.pfnRegisterVariable ( "joystick","0", FCVAR_ARCHIVE ); + joy_name = gEngfuncs.pfnRegisterVariable ( "joyname", "joystick", 0 ); + joy_advanced = gEngfuncs.pfnRegisterVariable ( "joyadvanced", "0", 0 ); + joy_advaxisx = gEngfuncs.pfnRegisterVariable ( "joyadvaxisx", "0", 0 ); + joy_advaxisy = gEngfuncs.pfnRegisterVariable ( "joyadvaxisy", "0", 0 ); + joy_advaxisz = gEngfuncs.pfnRegisterVariable ( "joyadvaxisz", "0", 0 ); + joy_advaxisr = gEngfuncs.pfnRegisterVariable ( "joyadvaxisr", "0", 0 ); + joy_advaxisu = gEngfuncs.pfnRegisterVariable ( "joyadvaxisu", "0", 0 ); + joy_advaxisv = gEngfuncs.pfnRegisterVariable ( "joyadvaxisv", "0", 0 ); + joy_forwardthreshold = gEngfuncs.pfnRegisterVariable ( "joyforwardthreshold", "0.15", 0 ); + joy_sidethreshold = gEngfuncs.pfnRegisterVariable ( "joysidethreshold", "0.15", 0 ); + joy_pitchthreshold = gEngfuncs.pfnRegisterVariable ( "joypitchthreshold", "0.15", 0 ); + joy_yawthreshold = gEngfuncs.pfnRegisterVariable ( "joyyawthreshold", "0.15", 0 ); + joy_forwardsensitivity = gEngfuncs.pfnRegisterVariable ( "joyforwardsensitivity", "-1.0", 0 ); + joy_sidesensitivity = gEngfuncs.pfnRegisterVariable ( "joysidesensitivity", "-1.0", 0 ); + joy_pitchsensitivity = gEngfuncs.pfnRegisterVariable ( "joypitchsensitivity", "1.0", 0 ); + joy_yawsensitivity = gEngfuncs.pfnRegisterVariable ( "joyyawsensitivity", "-1.0", 0 ); + joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 ); + joy_wwhack2 = gEngfuncs.pfnRegisterVariable ( "joywwhack2", "0.0", 0 ); - m_customaccel = gEngfuncs.pfnRegisterVariable ( "m_customaccel", "0", FCVAR_ARCHIVE ); - m_customaccel_scale = gEngfuncs.pfnRegisterVariable ( "m_customaccel_scale", "0.04", FCVAR_ARCHIVE ); - m_customaccel_max = gEngfuncs.pfnRegisterVariable ( "m_customaccel_max", "0", FCVAR_ARCHIVE ); - m_customaccel_exponent = gEngfuncs.pfnRegisterVariable ( "m_customaccel_exponent", "1", FCVAR_ARCHIVE ); + m_customaccel = gEngfuncs.pfnRegisterVariable ( "m_customaccel", "0", FCVAR_ARCHIVE ); + m_customaccel_scale = gEngfuncs.pfnRegisterVariable ( "m_customaccel_scale", "0.04", FCVAR_ARCHIVE ); + m_customaccel_max = gEngfuncs.pfnRegisterVariable ( "m_customaccel_max", "0", FCVAR_ARCHIVE ); + m_customaccel_exponent = gEngfuncs.pfnRegisterVariable ( "m_customaccel_exponent", "1", FCVAR_ARCHIVE ); #ifdef _WIN32 - m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; - m_bMouseThread = gEngfuncs.CheckParm ("-mousethread", NULL ) != NULL; - m_mousethread_sleep = gEngfuncs.pfnRegisterVariable ( "m_mousethread_sleep", "1", FCVAR_ARCHIVE ); // default to less than 1000 Hz + m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0; + m_bMouseThread = gEngfuncs.CheckParm ("-mousethread", NULL ) != NULL; + m_mousethread_sleep = gEngfuncs.pfnRegisterVariable ( "m_mousethread_sleep", "1", FCVAR_ARCHIVE ); // default to less than 1000 Hz - m_bMouseThread = m_bMouseThread && NULL != m_mousethread_sleep; + m_bMouseThread = m_bMouseThread && NULL != m_mousethread_sleep; - if (m_bMouseThread) - { - // init mouseThreadSleep: + if (m_bMouseThread) + { + // init mouseThreadSleep: #if 0 // _beginthreadex is not defined on VS 6? - InterlockedExchange(&mouseThreadSleep, (LONG)m_mousethread_sleep->value); + InterlockedExchange(&mouseThreadSleep, (LONG)m_mousethread_sleep->value); - s_hMouseQuitEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); - s_hMouseThreadActiveLock = CreateEvent( NULL, FALSE, TRUE, NULL ); - if ( s_hMouseQuitEvent && s_hMouseThreadActiveLock) - { - s_hMouseThread = (HANDLE)_beginthreadex( NULL, 0, MouseThread_Function, NULL, 0, &s_hMouseThreadId ); - } + s_hMouseQuitEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); + s_hMouseThreadActiveLock = CreateEvent( NULL, FALSE, TRUE, NULL ); + if ( s_hMouseQuitEvent && s_hMouseThreadActiveLock) + { + s_hMouseThread = (HANDLE)_beginthreadex( NULL, 0, MouseThread_Function, NULL, 0, &s_hMouseThreadId ); + } - m_bMouseThread = NULL != s_hMouseThread; + m_bMouseThread = NULL != s_hMouseThread; #else - m_bMouseThread = 0; + m_bMouseThread = 0; #endif - // at this early stage this won't print anything: - // gEngfuncs.Con_DPrintf ("Mouse thread %s.\n", m_bMouseThread ? "initalized" : "failed to initalize"); - } + // at this early stage this won't print anything: + // gEngfuncs.Con_DPrintf ("Mouse thread %s.\n", m_bMouseThread ? "initalized" : "failed to initalize"); + } #endif #ifdef USE_SDL2 @@ -1614,11 +1614,11 @@ void GoldSourceInput::IN_Init (void) gEngfuncs.Con_Printf("Could not load SDL2: %s\n", dlerror()); } #endif - gEngfuncs.pfnAddCommand ("force_centerview", Force_CenterView_f); - gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); + gEngfuncs.pfnAddCommand ("force_centerview", Force_CenterView_f); + gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); - IN_StartupMouse (); - IN_StartupJoystick (); + IN_StartupMouse (); + IN_StartupJoystick (); } #endif From 59269b1bb0c28ad49eb3d3c7e4b22834bceee57a Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 19 Dec 2018 13:39:22 +0300 Subject: [PATCH 181/211] cmake: remove useless second definition of 64BIT option --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 918449e3..80c2c5d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,6 @@ project (HLSDK-XASH3D) #-------------- # USER DEFINES \ ################\ -option(64BIT "Allow 64 Bit builds" OFF) option(USE_VGUI "Enable VGUI1. UNDONE" OFF) option(USE_VGUI2 "Enable VGUI2. UNDONE" OFF) option(USE_VOICEMGR "Enable VOICE MANAGER." OFF) From 43d63a1448e471ee47db5c706f08adaed2060f78 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Tue, 12 Feb 2019 05:01:29 +0300 Subject: [PATCH 182/211] Remove changing of m_szFriends on TalkInit (#58) --- dlls/scientist.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dlls/scientist.cpp b/dlls/scientist.cpp index 7e94b286..cc506b6f 100644 --- a/dlls/scientist.cpp +++ b/dlls/scientist.cpp @@ -695,12 +695,6 @@ void CScientist::TalkInit() { CTalkMonster::TalkInit(); - // scientist will try to talk to friends in this order: - - m_szFriends[0] = "monster_scientist"; - m_szFriends[1] = "monster_sitting_scientist"; - m_szFriends[2] = "monster_barney"; - // scientists speach group names (group names are in sentences.txt) m_szGrp[TLK_ANSWER] = "SC_ANSWER"; From 984dab64d39b59f9dc792f625607905853b10076 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 11 Apr 2019 13:26:02 +0300 Subject: [PATCH 183/211] Use line height from screen info in motd and scoreboard --- cl_dll/MOTD.cpp | 2 +- cl_dll/scoreboard.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cl_dll/MOTD.cpp b/cl_dll/MOTD.cpp index 179ae4a8..439fb9c4 100644 --- a/cl_dll/MOTD.cpp +++ b/cl_dll/MOTD.cpp @@ -56,7 +56,7 @@ void CHudMOTD::Reset( void ) m_bShow = 0; } -#define LINE_HEIGHT 13 +#define LINE_HEIGHT (gHUD.m_scrinfo.iCharHeight) #define ROW_GAP 13 #define ROW_RANGE_MIN 30 #define ROW_RANGE_MAX ( ScreenHeight - 100 ) diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index 5d52787c..d4bdecb8 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -108,7 +108,7 @@ We have a minimum width of 1-320 - we could have the field widths scale with it? int SCOREBOARD_WIDTH = 320; // Y positions -#define ROW_GAP 13 +#define ROW_GAP (gHUD.m_scrinfo.iCharHeight) #define ROW_RANGE_MIN 15 #define ROW_RANGE_MAX ( ScreenHeight - 50 ) From 073f442293113d958f501d8726df497cd94a91bb Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sat, 9 Feb 2019 20:30:51 +0300 Subject: [PATCH 184/211] Fix hornetgun recharge time on changelevel --- dlls/weapons.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 5e4f8f78..5daf07f6 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -1617,7 +1617,7 @@ IMPLEMENT_SAVERESTORE( CEgon, CBasePlayerWeapon ) TYPEDESCRIPTION CHgun::m_SaveData[] = { - DEFINE_FIELD( CHgun, m_flRechargeTime, FIELD_FLOAT ), + DEFINE_FIELD( CHgun, m_flRechargeTime, FIELD_TIME ), }; IMPLEMENT_SAVERESTORE( CHgun, CBasePlayerWeapon ) From 2b61380146b1d58a8c465f0e312c061b12bda115 Mon Sep 17 00:00:00 2001 From: FOTMarut Date: Tue, 12 Feb 2019 01:31:18 +0100 Subject: [PATCH 185/211] Fix for legacy node graph reading with XASH_64BIT - Added dlls/nodes_compat.h, which implements two stub classes for reading legacy CGraph and CLink - Modified CGraph::FLoadGraph in dlls/nodes.cpp to take advantage of them if GRAPH_VERSION != 16 == iVersion - Slight changes to dlls/nodes.h to be able to test for the value of GRAPH_VERSION in preprocessor directives --- dlls/nodes.cpp | 103 ++++++++++++++++++++------------ dlls/nodes.h | 5 +- dlls/nodes_compat.h | 141 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 40 deletions(-) create mode 100644 dlls/nodes_compat.h diff --git a/dlls/nodes.cpp b/dlls/nodes.cpp index 04705638..5e5b6acf 100644 --- a/dlls/nodes.cpp +++ b/dlls/nodes.cpp @@ -21,6 +21,7 @@ #include "cbase.h" #include "monsters.h" #include "nodes.h" +#include "nodes_compat.h" #include "animation.h" #include "doors.h" @@ -2386,42 +2387,47 @@ int CGraph::FLoadGraph( const char *szMapName ) pMemFile = aMemFile = LOAD_FILE_FOR_ME( szFilename, &length ); if( !aMemFile ) - { return FALSE; - } - else + + // Read the graph version number + // + length -= sizeof(int); + if( length < 0 ) + goto ShortFile; + iVersion = *(int *) pMemFile; + pMemFile += sizeof(int); + + if( iVersion == GRAPH_VERSION || iVersion == 16 ) { - // Read the graph version number - // - length -= sizeof(int); - if( length < 0 ) - goto ShortFile; - memcpy( &iVersion, pMemFile, sizeof(int) ); - pMemFile += sizeof(int); - - if( iVersion != GRAPH_VERSION ) - { - // This file was written by a different build of the dll! - // - ALERT( at_aiconsole, "**ERROR** Graph version is %d, expected %d\n", iVersion, GRAPH_VERSION ); - goto ShortFile; - } - // Read the graph class // - length -= sizeof(CGraph); - if( length < 0 ) - goto ShortFile; - memcpy( this, pMemFile, sizeof(CGraph) ); - pMemFile += sizeof(CGraph); + if ( iVersion == GRAPH_VERSION ) + { + length -= sizeof(CGraph); + if( length < 0 ) + goto ShortFile; + memcpy( this, pMemFile, sizeof(CGraph) ); + pMemFile += sizeof(CGraph); - // Set the pointers to zero, just in case we run out of memory. - // - m_pNodes = NULL; - m_pLinkPool = NULL; - m_di = NULL; - m_pRouteInfo = NULL; - m_pHashLinks = NULL; + // Set the pointers to zero, just in case we run out of memory. + // + m_pNodes = NULL; + m_pLinkPool = NULL; + m_di = NULL; + m_pRouteInfo = NULL; + m_pHashLinks = NULL; + } +#if _GRAPH_VERSION != 16 + else + { + ALERT( at_aiconsole, "Loading CGraph in GRAPH_VERSION 16 compatibility mode\n" ); + length -= sizeof(CGraph_32); + if( length < 0 ) + goto ShortFile; + reinterpret_cast(pMemFile) -> copyOverTo(this); + pMemFile += sizeof(CGraph_32); + } +#endif // Malloc for the nodes // @@ -2453,11 +2459,25 @@ int CGraph::FLoadGraph( const char *szMapName ) // Read in all the links // - length -= sizeof(CLink) * m_cLinks; - if( length < 0 ) - goto ShortFile; - memcpy( m_pLinkPool, pMemFile, sizeof(CLink) * m_cLinks ); - pMemFile += sizeof(CLink) * m_cLinks; + if( iVersion == GRAPH_VERSION ) + { + length -= sizeof(CLink) * m_cLinks; + if( length < 0 ) + goto ShortFile; + memcpy( m_pLinkPool, pMemFile, sizeof(CLink) * m_cLinks ); + pMemFile += sizeof(CLink) * m_cLinks; + } +#if _GRAPH_VERSION != 16 + else + { + ALERT( at_aiconsole, "Loading CLink array in GRAPH_VERSION 16 compatibility mode\n" ); + length -= sizeof(CLink_32) * m_cLinks; + if( length < 0 ) + goto ShortFile; + reinterpret_cast(pMemFile) -> copyOverTo(m_pLinkPool); + pMemFile += sizeof(CLink_32) * m_cLinks; + } +#endif // Malloc for the sorting info. // @@ -2482,7 +2502,7 @@ int CGraph::FLoadGraph( const char *szMapName ) m_pRouteInfo = (signed char *)calloc( sizeof(signed char), m_nRouteInfo ); if( !m_pRouteInfo ) { - ALERT( at_aiconsole, "***ERROR**\nCounldn't malloc %d route bytes!\n", m_nRouteInfo ); + ALERT( at_aiconsole, "***ERROR**\nCouldn't malloc %d route bytes!\n", m_nRouteInfo ); goto NoMemory; } m_CheckedCounter = 0; @@ -2505,7 +2525,7 @@ int CGraph::FLoadGraph( const char *szMapName ) m_pHashLinks = (short *)calloc( sizeof(short), m_nHashLinks ); if( !m_pHashLinks ) { - ALERT( at_aiconsole, "***ERROR**\nCounldn't malloc %d hash link bytes!\n", m_nHashLinks ); + ALERT( at_aiconsole, "***ERROR**\nCouldn't malloc %d hash link bytes!\n", m_nHashLinks ); goto NoMemory; } @@ -2531,6 +2551,13 @@ int CGraph::FLoadGraph( const char *szMapName ) return TRUE; } + else + { + // This file was written by a different build of the dll! + // + ALERT( at_aiconsole, "**ERROR** Graph version is %d, expected %d\n", iVersion, GRAPH_VERSION ); + goto ShortFile; + } ShortFile: NoMemory: diff --git a/dlls/nodes.h b/dlls/nodes.h index 52b715e5..f43684c8 100644 --- a/dlls/nodes.h +++ b/dlls/nodes.h @@ -106,10 +106,11 @@ typedef struct // CGraph //========================================================= #ifdef XASH_64BIT -#define GRAPH_VERSION (int)16 * 10 +#define _GRAPH_VERSION (16 * 10) #else -#define GRAPH_VERSION (int)16// !!!increment this whever graph/node/link classes change, to obsolesce older disk files. +#define _GRAPH_VERSION (16)// !!!increment this whever graph/node/link classes change, to obsolesce older disk files. #endif +#define GRAPH_VERSION (int)_GRAPH_VERSION class CGraph { diff --git a/dlls/nodes_compat.h b/dlls/nodes_compat.h new file mode 100644 index 00000000..da91a5b8 --- /dev/null +++ b/dlls/nodes_compat.h @@ -0,0 +1,141 @@ + +#pragma once +#ifndef NODES_32BIT_COMPAT +#define NODES_32BIT_COMPAT + +//#include "nodes.h" + +#if _GRAPH_VERSION != 16 + +#include "stdint.h" + +typedef int32_t PTR32; + +class CGraph_32 +{ +public: + + BOOL m_fGraphPresent; + BOOL m_fGraphPointersSet; + BOOL m_fRoutingComplete; + + PTR32 m_pNodes; // CNode* + PTR32 m_pLinkPool; // CLink* + PTR32 m_pRouteInfo; // signed char* + + int m_cNodes; + int m_cLinks; + int m_nRouteInfo; + + PTR32 m_di; // DIST_INFO* + int m_RangeStart[3][NUM_RANGES]; + int m_RangeEnd[3][NUM_RANGES]; + float m_flShortest; + int m_iNearest; + int m_minX, m_minY, m_minZ, m_maxX, m_maxY, m_maxZ; + int m_minBoxX, m_minBoxY, m_minBoxZ, m_maxBoxX, m_maxBoxY, m_maxBoxZ; + int m_CheckedCounter; + float m_RegionMin[3], m_RegionMax[3]; + CACHE_ENTRY m_Cache[CACHE_SIZE]; + + + int m_HashPrimes[16]; + PTR32 m_pHashLinks; // short* + int m_nHashLinks; + + int m_iLastActiveIdleSearch; + + int m_iLastCoverSearch; + + + void copyOverTo(CGraph *other) { + other->m_fGraphPresent = m_fGraphPresent; + other->m_fGraphPointersSet = m_fGraphPointersSet; + other->m_fRoutingComplete = m_fRoutingComplete; + + other->m_pNodes = NULL; + other->m_pLinkPool = NULL; + other->m_pRouteInfo = NULL; + + other->m_cNodes = m_cNodes; + other->m_cLinks = m_cLinks; + other->m_nRouteInfo = m_nRouteInfo; + + other->m_di = NULL; +#if _GRAPH_VERSION == 160 + memcpy( (void *) &other->m_RangeStart, (void *) m_RangeStart, + offsetof(class CGraph, m_pHashLinks) - offsetof(class CGraph, m_RangeStart) ); +#else // fallback routine if the graph version changes + for (int i = 0; i < 3; ++i) + for (int j = 0; j < NUM_RANGES; ++j) + other->m_RangeStart[i][j] = m_RangeStart[i][j]; +// m_RangeStart[3][NUM_RANGES] + for (int i = 0; i < 3; ++i) + for (int j = 0; j < NUM_RANGES; ++j) + other->m_RangeEnd[i][j] = m_RangeEnd[i][j]; +// m_RangeEnd[3][NUM_RANGES] + other->m_flShortest = m_flShortest; + other->m_iNearest = m_iNearest; + other->m_minX = m_minX; + other->m_minY = m_minY; + other->m_minZ = m_minZ; + other->m_maxX = m_maxX; + other->m_maxY = m_maxY; + other->m_maxZ = m_maxZ; + other->m_minBoxX = m_minBoxX; + other->m_minBoxY = m_minBoxY; + other->m_minBoxZ = m_minBoxZ; + other->m_maxBoxX = m_maxBoxX; + other->m_maxBoxY = m_maxBoxY; + other->m_maxBoxZ = m_maxBoxZ; + other->m_CheckedCounter = m_CheckedCounter; + for (int i = 0; i < 3; ++i) + other->m_RegionMin[i] = m_RegionMin[i]; +// m_RegionMin[3] + for (int i = 0; i < 3; ++i) + other->m_RegionMax[i] = m_RegionMax[i]; +// m_RegionMax[3] + for (int i = 0; i < CACHE_SIZE; ++i) + other->m_Cache[i] = m_Cache[i]; +// m_Cache[CACHE_SIZE] + for (int i = 0; i < 16; ++i) + other->m_HashPrimes[i] = m_HashPrimes[i]; +// m_HashPrimes[16] +#endif + other->m_pHashLinks = NULL; + other->m_nHashLinks = m_nHashLinks; + + other->m_iLastActiveIdleSearch = m_iLastActiveIdleSearch; + + other->m_iLastCoverSearch = m_iLastCoverSearch; + + } + +}; + + +class CLink_32 +{ + +public: + int m_iSrcNode; + int m_iDestNode; + PTR32 m_pLinkEnt; // entvars_t* + char m_szLinkEntModelname[ 4 ]; + int m_afLinkInfo; + float m_flWeight; + + void copyOverTo(CLink* other) { + other->m_iSrcNode = m_iSrcNode; + other->m_iDestNode = m_iDestNode ; + other->m_pLinkEnt = NULL; + for (int i = 0; i < 4; ++i) + other->m_szLinkEntModelname[i] = m_szLinkEntModelname[i]; +// m_szLinkEntModelname[ 4 ] + other->m_afLinkInfo = m_afLinkInfo; + other->m_flWeight = m_flWeight; + } +}; + +#endif +#endif From 8ef6cb2427ee16a763103bd3f315f38e2f01cfe2 Mon Sep 17 00:00:00 2001 From: FOTMarut Date: Sat, 16 Feb 2019 17:32:45 +0100 Subject: [PATCH 186/211] Replaced magic numbers with defines in dlls/nodes* - Changed some symbols to be platform-independent - Now the CGraph_Retail::copyOverTo method doesn't automatically fall back to manual copy (instead of memcpy) on GRAPH_VERSION increments --- dlls/nodes.cpp | 18 +++++++++--------- dlls/nodes.h | 4 +++- dlls/nodes_compat.h | 12 +++++++----- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/dlls/nodes.cpp b/dlls/nodes.cpp index 5e5b6acf..e81f3252 100644 --- a/dlls/nodes.cpp +++ b/dlls/nodes.cpp @@ -2397,7 +2397,7 @@ int CGraph::FLoadGraph( const char *szMapName ) iVersion = *(int *) pMemFile; pMemFile += sizeof(int); - if( iVersion == GRAPH_VERSION || iVersion == 16 ) + if( iVersion == GRAPH_VERSION || iVersion == GRAPH_VERSION_RETAIL ) { // Read the graph class // @@ -2417,15 +2417,15 @@ int CGraph::FLoadGraph( const char *szMapName ) m_pRouteInfo = NULL; m_pHashLinks = NULL; } -#if _GRAPH_VERSION != 16 +#if _GRAPH_VERSION != _GRAPH_VERSION_RETAIL else { ALERT( at_aiconsole, "Loading CGraph in GRAPH_VERSION 16 compatibility mode\n" ); - length -= sizeof(CGraph_32); + length -= sizeof(CGraph_Retail); if( length < 0 ) goto ShortFile; - reinterpret_cast(pMemFile) -> copyOverTo(this); - pMemFile += sizeof(CGraph_32); + reinterpret_cast(pMemFile) -> copyOverTo(this); + pMemFile += sizeof(CGraph_Retail); } #endif @@ -2467,15 +2467,15 @@ int CGraph::FLoadGraph( const char *szMapName ) memcpy( m_pLinkPool, pMemFile, sizeof(CLink) * m_cLinks ); pMemFile += sizeof(CLink) * m_cLinks; } -#if _GRAPH_VERSION != 16 +#if _GRAPH_VERSION != _GRAPH_VERSION_RETAIL else { ALERT( at_aiconsole, "Loading CLink array in GRAPH_VERSION 16 compatibility mode\n" ); - length -= sizeof(CLink_32) * m_cLinks; + length -= sizeof(CLink_Retail) * m_cLinks; if( length < 0 ) goto ShortFile; - reinterpret_cast(pMemFile) -> copyOverTo(m_pLinkPool); - pMemFile += sizeof(CLink_32) * m_cLinks; + reinterpret_cast(pMemFile) -> copyOverTo(m_pLinkPool); + pMemFile += sizeof(CLink_Retail) * m_cLinks; } #endif diff --git a/dlls/nodes.h b/dlls/nodes.h index f43684c8..4bc1ec1b 100644 --- a/dlls/nodes.h +++ b/dlls/nodes.h @@ -105,12 +105,14 @@ typedef struct //========================================================= // CGraph //========================================================= +#define _GRAPH_VERSION_RETAIL 16 // Retail Half-Life graph version. Don't increment this #ifdef XASH_64BIT #define _GRAPH_VERSION (16 * 10) #else -#define _GRAPH_VERSION (16)// !!!increment this whever graph/node/link classes change, to obsolesce older disk files. +#define _GRAPH_VERSION (16) // !!!increment this whenever graph/node/link classes change, to obsolesce older disk files. #endif #define GRAPH_VERSION (int)_GRAPH_VERSION +#define GRAPH_VERSION_RETAIL (int)_GRAPH_VERSION_RETAIL class CGraph { diff --git a/dlls/nodes_compat.h b/dlls/nodes_compat.h index da91a5b8..d73567e9 100644 --- a/dlls/nodes_compat.h +++ b/dlls/nodes_compat.h @@ -5,13 +5,13 @@ //#include "nodes.h" -#if _GRAPH_VERSION != 16 +#if _GRAPH_VERSION != _GRAPH_VERSION_RETAIL #include "stdint.h" typedef int32_t PTR32; -class CGraph_32 +class CGraph_Retail { public: @@ -62,10 +62,11 @@ public: other->m_nRouteInfo = m_nRouteInfo; other->m_di = NULL; -#if _GRAPH_VERSION == 160 + memcpy( (void *) &other->m_RangeStart, (void *) m_RangeStart, offsetof(class CGraph, m_pHashLinks) - offsetof(class CGraph, m_RangeStart) ); -#else // fallback routine if the graph version changes + +#if 0 // replacement routine in case a change in CGraph breaks the above memcpy for (int i = 0; i < 3; ++i) for (int j = 0; j < NUM_RANGES; ++j) other->m_RangeStart[i][j] = m_RangeStart[i][j]; @@ -102,6 +103,7 @@ public: other->m_HashPrimes[i] = m_HashPrimes[i]; // m_HashPrimes[16] #endif + other->m_pHashLinks = NULL; other->m_nHashLinks = m_nHashLinks; @@ -114,7 +116,7 @@ public: }; -class CLink_32 +class CLink_Retail { public: From c041db99097241996d802fef42e5d4f28e549246 Mon Sep 17 00:00:00 2001 From: mittorn Date: Sat, 4 Aug 2018 20:59:07 +0700 Subject: [PATCH 187/211] Prevent skipping SetMoveDone call --- dlls/subs.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dlls/subs.cpp b/dlls/subs.cpp index 2a299ce4..e24a5c08 100644 --- a/dlls/subs.cpp +++ b/dlls/subs.cpp @@ -407,6 +407,13 @@ void CBaseToggle::LinearMove( Vector vecDest, float flSpeed ) // divide vector length by speed to get time to reach dest float flTravelTime = vecDestDelta.Length() / flSpeed; + if( flTravelTime < 0.05 ) + { + UTIL_SetOrigin( pev, m_vecFinalDest ); + LinearMoveDone(); + return; + } + // set nextthink to trigger a call to LinearMoveDone when dest is reached pev->nextthink = pev->ltime + flTravelTime; SetThink( &CBaseToggle::LinearMoveDone ); From 86229f7926bebdb920e88f1877d8d8398032165c Mon Sep 17 00:00:00 2001 From: Night Owl Date: Fri, 18 Jan 2019 17:41:41 +0500 Subject: [PATCH 188/211] Add cvar to skip unicode check(Same as https://github.com/FWGS/halflife/commit/4cdb80dce75efb7fc57fa636ea56b8bed247f176) --- dlls/client.cpp | 5 +++++ dlls/game.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/dlls/client.cpp b/dlls/client.cpp index 1e7dab72..80b16945 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -51,6 +51,7 @@ extern int gmsgSayText; extern int gmsgBhopcap; extern cvar_t allow_spectators; +extern cvar_t multibyte_only; extern int g_teamplay; @@ -287,6 +288,10 @@ decodeFinishedMaybeCESU8: bool Q_UnicodeValidate( const char *pUTF8 ) { bool bError = false; + + if( !multibyte_only.value ) + return true; + while( *pUTF8 ) { unsigned int uVal; diff --git a/dlls/game.cpp b/dlls/game.cpp index 4354a63d..284e5a9d 100644 --- a/dlls/game.cpp +++ b/dlls/game.cpp @@ -43,6 +43,7 @@ cvar_t allowmonsters = { "mp_allowmonsters","0", FCVAR_SERVER }; cvar_t bhopcap = { "mp_bhopcap", "1", FCVAR_SERVER }; cvar_t allow_spectators = { "allow_spectators", "0", FCVAR_SERVER }; // 0 prevents players from being spectators +cvar_t multibyte_only = { "mp_multibyte_only", "0", FCVAR_SERVER }; cvar_t mp_chattime = { "mp_chattime","10", FCVAR_SERVER }; @@ -480,6 +481,7 @@ void GameDLLInit( void ) CVAR_REGISTER( &defaultteam ); CVAR_REGISTER( &allowmonsters ); CVAR_REGISTER( &bhopcap ); + CVAR_REGISTER( &multibyte_only ); CVAR_REGISTER( &mp_chattime ); From ea6fa67c8723c5ef0eb6380593d83abb8124f3cb Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 11 Apr 2019 13:49:08 +0300 Subject: [PATCH 189/211] Fix potential crash / data corruption in hud message --- cl_dll/message.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cl_dll/message.cpp b/cl_dll/message.cpp index ff8d97bf..a8665c9f 100644 --- a/cl_dll/message.cpp +++ b/cl_dll/message.cpp @@ -281,9 +281,12 @@ void CHudMessage::MessageDrawScan( client_textmessage_t *pMessage, float time ) while( *pText && *pText != '\n' ) { unsigned char c = *pText; - line[m_parms.lineLength] = c; - m_parms.width += gHUD.m_scrinfo.charWidths[c]; - m_parms.lineLength++; + if (m_parms.lineLength < sizeof(line)-1) + { + line[m_parms.lineLength] = c; + m_parms.width += gHUD.m_scrinfo.charWidths[c]; + m_parms.lineLength++; + } pText++; } pText++; // Skip LF From f2f83cd0359d0453ecdd4116f814c106560e9142 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 11 Apr 2019 17:21:47 +0300 Subject: [PATCH 190/211] Allow hud messages or arbitrary length --- cl_dll/message.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cl_dll/message.cpp b/cl_dll/message.cpp index a8665c9f..bbd59d9a 100644 --- a/cl_dll/message.cpp +++ b/cl_dll/message.cpp @@ -240,7 +240,7 @@ void CHudMessage::MessageDrawScan( client_textmessage_t *pMessage, float time ) { int i, j, length, width; const char *pText; - unsigned char line[80]; + const char *pLineStart; pText = pMessage->pMessage; // Count lines @@ -278,25 +278,21 @@ void CHudMessage::MessageDrawScan( client_textmessage_t *pMessage, float time ) { m_parms.lineLength = 0; m_parms.width = 0; + pLineStart = pText; while( *pText && *pText != '\n' ) { unsigned char c = *pText; - if (m_parms.lineLength < sizeof(line)-1) - { - line[m_parms.lineLength] = c; - m_parms.width += gHUD.m_scrinfo.charWidths[c]; - m_parms.lineLength++; - } + m_parms.width += gHUD.m_scrinfo.charWidths[c]; + m_parms.lineLength++; pText++; } pText++; // Skip LF - line[m_parms.lineLength] = 0; m_parms.x = XPosition( pMessage->x, m_parms.width, m_parms.totalWidth ); for( j = 0; j < m_parms.lineLength; j++ ) { - m_parms.text = line[j]; + m_parms.text = pLineStart[j]; int next = m_parms.x + gHUD.m_scrinfo.charWidths[m_parms.text]; MessageScanNextChar(); From 76b7df393ae5fb594e13b38a1c8d106aa6b1db7f Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 2 May 2019 02:54:23 +0300 Subject: [PATCH 191/211] Add spaces between source files in compile.bat --- cl_dll/compile.bat | 124 ++++++++++++++-------------- dlls/compile.bat | 198 ++++++++++++++++++++++----------------------- 2 files changed, 161 insertions(+), 161 deletions(-) diff --git a/cl_dll/compile.bat b/cl_dll/compile.bat index 9270d4bc..18b45459 100644 --- a/cl_dll/compile.bat +++ b/cl_dll/compile.bat @@ -8,68 +8,68 @@ echo -- Compiler is MSVC6 set XASH3DSRC=..\..\Xash3D_original set INCLUDES=-I../common -I../engine -I../pm_shared -I../game_shared -I../public -I../external -I../dlls -I../utils/false_vgui/include -set SOURCES=../dlls/crossbow.cpp^ - ../dlls/crowbar.cpp^ - ../dlls/egon.cpp^ - ../dlls/gauss.cpp^ - ../dlls/handgrenade.cpp^ - ../dlls/hornetgun.cpp^ - ../dlls/mp5.cpp^ - ../dlls/python.cpp^ - ../dlls/rpg.cpp^ - ../dlls/satchel.cpp^ - ../dlls/shotgun.cpp^ - ../dlls/squeakgrenade.cpp^ - ../dlls/tripmine.cpp^ - ../dlls/glock.cpp^ - ev_hldm.cpp^ - hl/hl_baseentity.cpp^ - hl/hl_events.cpp^ - hl/hl_objects.cpp^ - hl/hl_weapons.cpp^ - ammo.cpp^ - ammo_secondary.cpp^ - ammohistory.cpp^ - battery.cpp^ - cdll_int.cpp^ - com_weapons.cpp^ - death.cpp^ - demo.cpp^ - entity.cpp^ - ev_common.cpp^ - events.cpp^ - flashlight.cpp^ - GameStudioModelRenderer.cpp^ - geiger.cpp^ - health.cpp^ - hud.cpp^ - hud_msg.cpp^ - hud_redraw.cpp^ - hud_spectator.cpp^ - hud_update.cpp^ - in_camera.cpp^ - input.cpp^ - input_goldsource.cpp^ - input_mouse.cpp^ - input_xash3d.cpp^ - menu.cpp^ - message.cpp^ - overview.cpp^ - parsemsg.cpp^ - ../pm_shared/pm_debug.c^ - ../pm_shared/pm_math.c^ - ../pm_shared/pm_shared.c^ - saytext.cpp^ - status_icons.cpp^ - statusbar.cpp^ - studio_util.cpp^ - StudioModelRenderer.cpp^ - text_message.cpp^ - train.cpp^ - tri.cpp^ - util.cpp^ - view.cpp^ - scoreboard.cpp^ +set SOURCES=../dlls/crossbow.cpp ^ + ../dlls/crowbar.cpp ^ + ../dlls/egon.cpp ^ + ../dlls/gauss.cpp ^ + ../dlls/handgrenade.cpp ^ + ../dlls/hornetgun.cpp ^ + ../dlls/mp5.cpp ^ + ../dlls/python.cpp ^ + ../dlls/rpg.cpp ^ + ../dlls/satchel.cpp ^ + ../dlls/shotgun.cpp ^ + ../dlls/squeakgrenade.cpp ^ + ../dlls/tripmine.cpp ^ + ../dlls/glock.cpp ^ + ev_hldm.cpp ^ + hl/hl_baseentity.cpp ^ + hl/hl_events.cpp ^ + hl/hl_objects.cpp ^ + hl/hl_weapons.cpp ^ + ammo.cpp ^ + ammo_secondary.cpp ^ + ammohistory.cpp ^ + battery.cpp ^ + cdll_int.cpp ^ + com_weapons.cpp ^ + death.cpp ^ + demo.cpp ^ + entity.cpp ^ + ev_common.cpp ^ + events.cpp ^ + flashlight.cpp ^ + GameStudioModelRenderer.cpp ^ + geiger.cpp ^ + health.cpp ^ + hud.cpp ^ + hud_msg.cpp ^ + hud_redraw.cpp ^ + hud_spectator.cpp ^ + hud_update.cpp ^ + in_camera.cpp ^ + input.cpp ^ + input_goldsource.cpp ^ + input_mouse.cpp ^ + input_xash3d.cpp ^ + menu.cpp ^ + message.cpp ^ + overview.cpp ^ + parsemsg.cpp ^ + ../pm_shared/pm_debug.c ^ + ../pm_shared/pm_math.c ^ + ../pm_shared/pm_shared.c ^ + saytext.cpp ^ + status_icons.cpp ^ + statusbar.cpp ^ + studio_util.cpp ^ + StudioModelRenderer.cpp ^ + text_message.cpp ^ + train.cpp ^ + tri.cpp ^ + util.cpp ^ + view.cpp ^ + scoreboard.cpp ^ MOTD.cpp set DEFINES=/DCLIENT_DLL /DCLIENT_WEAPONS /Dsnprintf=_snprintf /DNO_VOICEGAMEMGR /DGOLDSOURCE_SUPPORT set LIBS=user32.lib Winmm.lib diff --git a/dlls/compile.bat b/dlls/compile.bat index 53c4511b..f97806a5 100644 --- a/dlls/compile.bat +++ b/dlls/compile.bat @@ -8,105 +8,105 @@ echo -- Compiler is MSVC6 set XASH3DSRC=..\..\Xash3D_original set INCLUDES=-I../common -I../engine -I../pm_shared -I../game_shared -I../public -set SOURCES=agrunt.cpp^ - airtank.cpp^ - aflock.cpp^ - animating.cpp^ - animation.cpp^ - apache.cpp^ - barnacle.cpp^ - barney.cpp^ - bigmomma.cpp^ - bloater.cpp^ - bmodels.cpp^ - bullsquid.cpp^ - buttons.cpp^ - cbase.cpp^ - client.cpp^ - combat.cpp^ - controller.cpp^ - crossbow.cpp^ - crowbar.cpp^ - defaultai.cpp^ - doors.cpp^ - effects.cpp^ - egon.cpp^ - explode.cpp^ - flyingmonster.cpp^ - func_break.cpp^ - func_tank.cpp^ - game.cpp^ - gamerules.cpp^ - gargantua.cpp^ - gauss.cpp^ - genericmonster.cpp^ - ggrenade.cpp^ - globals.cpp^ - glock.cpp^ - gman.cpp^ - h_ai.cpp^ - h_battery.cpp^ - h_cine.cpp^ - h_cycler.cpp^ - h_export.cpp^ - handgrenade.cpp^ - hassassin.cpp^ - headcrab.cpp^ - healthkit.cpp^ - hgrunt.cpp^ - hornet.cpp^ - hornetgun.cpp^ - houndeye.cpp^ - ichthyosaur.cpp^ - islave.cpp^ - items.cpp^ - leech.cpp^ - lights.cpp^ - maprules.cpp^ - monstermaker.cpp^ - monsters.cpp^ - monsterstate.cpp^ - mortar.cpp^ - mp5.cpp^ - multiplay_gamerules.cpp^ - nihilanth.cpp^ - nodes.cpp^ - observer.cpp^ - osprey.cpp^ - pathcorner.cpp^ - plane.cpp^ - plats.cpp^ - player.cpp^ - playermonster.cpp^ - python.cpp^ - rat.cpp^ - roach.cpp^ - rpg.cpp^ - satchel.cpp^ - schedule.cpp^ - scientist.cpp^ - scripted.cpp^ - shotgun.cpp^ - singleplay_gamerules.cpp^ - skill.cpp^ - sound.cpp^ - soundent.cpp^ - spectator.cpp^ - squadmonster.cpp^ - squeakgrenade.cpp^ - subs.cpp^ - talkmonster.cpp^ - teamplay_gamerules.cpp^ - tempmonster.cpp^ - tentacle.cpp^ - triggers.cpp^ - tripmine.cpp^ - turret.cpp^ - util.cpp^ - weapons.cpp^ - world.cpp^ - xen.cpp^ - zombie.cpp^ +set SOURCES=agrunt.cpp ^ + airtank.cpp ^ + aflock.cpp ^ + animating.cpp ^ + animation.cpp ^ + apache.cpp ^ + barnacle.cpp ^ + barney.cpp ^ + bigmomma.cpp ^ + bloater.cpp ^ + bmodels.cpp ^ + bullsquid.cpp ^ + buttons.cpp ^ + cbase.cpp ^ + client.cpp ^ + combat.cpp ^ + controller.cpp ^ + crossbow.cpp ^ + crowbar.cpp ^ + defaultai.cpp ^ + doors.cpp ^ + effects.cpp ^ + egon.cpp ^ + explode.cpp ^ + flyingmonster.cpp ^ + func_break.cpp ^ + func_tank.cpp ^ + game.cpp ^ + gamerules.cpp ^ + gargantua.cpp ^ + gauss.cpp ^ + genericmonster.cpp ^ + ggrenade.cpp ^ + globals.cpp ^ + glock.cpp ^ + gman.cpp ^ + h_ai.cpp ^ + h_battery.cpp ^ + h_cine.cpp ^ + h_cycler.cpp ^ + h_export.cpp ^ + handgrenade.cpp ^ + hassassin.cpp ^ + headcrab.cpp ^ + healthkit.cpp ^ + hgrunt.cpp ^ + hornet.cpp ^ + hornetgun.cpp ^ + houndeye.cpp ^ + ichthyosaur.cpp ^ + islave.cpp ^ + items.cpp ^ + leech.cpp ^ + lights.cpp ^ + maprules.cpp ^ + monstermaker.cpp ^ + monsters.cpp ^ + monsterstate.cpp ^ + mortar.cpp ^ + mp5.cpp ^ + multiplay_gamerules.cpp ^ + nihilanth.cpp ^ + nodes.cpp ^ + observer.cpp ^ + osprey.cpp ^ + pathcorner.cpp ^ + plane.cpp ^ + plats.cpp ^ + player.cpp ^ + playermonster.cpp ^ + python.cpp ^ + rat.cpp ^ + roach.cpp ^ + rpg.cpp ^ + satchel.cpp ^ + schedule.cpp ^ + scientist.cpp ^ + scripted.cpp ^ + shotgun.cpp ^ + singleplay_gamerules.cpp ^ + skill.cpp ^ + sound.cpp ^ + soundent.cpp ^ + spectator.cpp ^ + squadmonster.cpp ^ + squeakgrenade.cpp ^ + subs.cpp ^ + talkmonster.cpp ^ + teamplay_gamerules.cpp ^ + tempmonster.cpp ^ + tentacle.cpp ^ + triggers.cpp ^ + tripmine.cpp ^ + turret.cpp ^ + util.cpp ^ + weapons.cpp ^ + world.cpp ^ + xen.cpp ^ + zombie.cpp ^ ../pm_shared/pm_debug.c ../pm_shared/pm_math.c ../pm_shared/pm_shared.c set DEFINES=/DCLIENT_WEAPONS /Dsnprintf=_snprintf /DNO_VOICEGAMEMGR set LIBS=user32.lib From f7e51e2c204514c47dac41c1a4fa4bbfba2e1ac5 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Thu, 2 May 2019 03:24:19 +0300 Subject: [PATCH 192/211] Stop uncontrollable camera rotating when raw mouse input is on --- cl_dll/input_goldsource.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index ae6d83e2..be85ee3a 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -599,9 +599,13 @@ void IN_ResetMouse( void ) // no work to do in SDL #ifdef _WIN32 // reset only if mouse is active and not in visible mode: - if(mouseactive && !iVisibleMouse) + if(mouseactive && !iVisibleMouse && gEngfuncs.GetWindowCenterX && gEngfuncs.GetWindowCenterY) { - if ( !m_bRawInput && gEngfuncs.GetWindowCenterX && gEngfuncs.GetWindowCenterY ) + if ( !m_bMouseThread && m_bRawInput ) + { + SetCursorPos ( gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY() ); + } + else if ( !m_bRawInput ) { bool lockEntered = MouseThread_ActiveLock_Enter(); From 470a71540b9071a1e103b8d59f23d215bd568f4b Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 3 May 2019 19:19:39 +0300 Subject: [PATCH 193/211] waf: initial deploy --- .gitignore | 3 + cl_dll/wscript | 69 +++ dlls/wscript | 75 ++++ scripts/waflib/deps.py | 65 +++ scripts/waflib/force_32bit.py | 56 +++ scripts/waflib/fwgslib.py | 30 ++ scripts/waflib/msdev.py | 774 ++++++++++++++++++++++++++++++++++ scripts/waflib/reconfigure.py | 47 +++ scripts/waflib/xcompile.py | 208 +++++++++ waf | 170 ++++++++ wscript | 149 +++++++ 11 files changed, 1646 insertions(+) create mode 100644 cl_dll/wscript create mode 100644 dlls/wscript create mode 100644 scripts/waflib/deps.py create mode 100644 scripts/waflib/force_32bit.py create mode 100644 scripts/waflib/fwgslib.py create mode 100644 scripts/waflib/msdev.py create mode 100644 scripts/waflib/reconfigure.py create mode 100644 scripts/waflib/xcompile.py create mode 100755 waf create mode 100644 wscript diff --git a/.gitignore b/.gitignore index a0bc5604..adcc4f7b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,6 @@ cmake_install.cmake *.vsxproj *.vsproj *.sln +.waf-* +.lock* +*.pyc diff --git a/cl_dll/wscript b/cl_dll/wscript new file mode 100644 index 00000000..85de7e55 --- /dev/null +++ b/cl_dll/wscript @@ -0,0 +1,69 @@ +#! /usr/bin/env python +# encoding: utf-8 +# a1batross, mittorn, 2018 + +from waflib import Utils +import os + +def options(opt): + # stub + return + +def configure(conf): + if conf.env.GOLDSRC: + if conf.env.DEST_OS != 'win32': + conf.check_cc(lib='dl') + +def build(bld): + source = bld.path.parent.ant_glob([ + 'pm_shared/*.c', + 'dlls/crossbow.cpp', 'dlls/crowbar.cpp', 'dlls/egon.cpp', 'dlls/gauss.cpp', 'dlls/handgrenade.cpp', + 'dlls/hornetgun.cpp', 'dlls/mp5.cpp', 'dlls/python.cpp', 'dlls/rpg.cpp', 'dlls/satchel.cpp', + 'dlls/shotgun.cpp', 'dlls/squeakgrenade.cpp', 'dlls/tripmine.cpp', 'dlls/glock.cpp' + ]) + + source += bld.path.ant_glob(['hl/*.cpp']) + source += [ + 'ev_hldm.cpp', 'ammo.cpp', 'ammo_secondary.cpp', 'ammohistory.cpp', + 'battery.cpp', 'cdll_int.cpp', 'com_weapons.cpp', 'death.cpp', + 'demo.cpp', 'entity.cpp', 'ev_common.cpp', 'events.cpp', + 'flashlight.cpp', 'GameStudioModelRenderer.cpp', 'geiger.cpp', + 'health.cpp', 'hud.cpp', 'hud_msg.cpp', 'hud_redraw.cpp', + 'hud_spectator.cpp', 'hud_update.cpp', 'in_camera.cpp', + 'input.cpp', 'input_goldsource.cpp', 'input_mouse.cpp', + 'input_xash3d.cpp', 'menu.cpp', 'message.cpp', + 'overview.cpp', 'parsemsg.cpp', 'saytext.cpp', + 'status_icons.cpp', 'statusbar.cpp', 'studio_util.cpp', + 'StudioModelRenderer.cpp', 'text_message.cpp', 'train.cpp', + 'tri.cpp', 'util.cpp', 'view.cpp', 'scoreboard.cpp', 'MOTD.cpp' + ] + + includes = Utils.to_list('. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public ../utils/false_vgui/include') + + defines = ['CLIENT_DLL'] + if bld.env.GOLDSRC: + defines += ['GOLDSOURCE_SUPPORT'] + + libs = [] + if bld.env.GOLDSRC: + libs += ['DL'] + + if bld.env.DEST_OS == 'win32': + libname = 'client.dll' + elif bld.env.DEST_OS == 'linux': + libname = 'client.so' + elif bld.env.DEST_OS == 'darwin': + libname = 'client.dylib' + else: libname = '' + + bld.shlib( + source = source, + target = 'client', + features = 'c cxx', + includes = includes, + defines = defines, + use = libs, + install_path = os.path.join(bld.env.GAMEDIR, bld.env.CLIENT_DIR, libname), + subsystem = bld.env.MSVC_SUBSYSTEM, + idx = 1 + ) diff --git a/dlls/wscript b/dlls/wscript new file mode 100644 index 00000000..95581ff7 --- /dev/null +++ b/dlls/wscript @@ -0,0 +1,75 @@ +#! /usr/bin/env python +# encoding: utf-8 +# a1batross, mittorn, 2018 + +from waflib import Utils +import os + +def options(opt): + # stub + return + +def configure(conf): + # stub + return + +def build(bld): + defines = [] + source = bld.path.parent.ant_glob([ + 'pm_shared/*.c', + ]) + + source += [ + 'agrunt.cpp', 'airtank.cpp', 'aflock.cpp', 'animating.cpp', 'animation.cpp', 'apache.cpp', + 'barnacle.cpp', 'barney.cpp', 'bigmomma.cpp', 'bloater.cpp', 'bmodels.cpp', 'bullsquid.cpp', 'buttons.cpp', + 'cbase.cpp', 'client.cpp', 'combat.cpp', 'controller.cpp', 'crossbow.cpp', 'crowbar.cpp', + 'defaultai.cpp', 'doors.cpp', + 'effects.cpp', 'egon.cpp', 'explode.cpp', + 'flyingmonster.cpp', 'func_break.cpp', 'func_tank.cpp', + 'game.cpp', 'gamerules.cpp', 'gargantua.cpp', 'gauss.cpp', 'genericmonster.cpp', 'ggrenade.cpp', 'globals.cpp', 'glock.cpp', 'gman.cpp', + 'h_ai.cpp', 'h_battery.cpp', 'h_cine.cpp', 'h_cycler.cpp', 'h_export.cpp', 'handgrenade.cpp', 'hassassin.cpp', 'headcrab.cpp', + 'healthkit.cpp', 'hgrunt.cpp', 'hornet.cpp', 'hornetgun.cpp', 'houndeye.cpp', + 'ichthyosaur.cpp', 'islave.cpp', 'items.cpp', + 'leech.cpp', 'lights.cpp', + 'maprules.cpp', 'monstermaker.cpp', 'monsters.cpp', 'monsterstate.cpp', 'mortar.cpp', 'mp5.cpp', 'multiplay_gamerules.cpp', + 'nihilanth.cpp', 'nodes.cpp', + 'observer.cpp', 'osprey.cpp', + 'pathcorner.cpp', 'plane.cpp', 'plats.cpp', 'player.cpp', 'playermonster.cpp', 'python.cpp', + 'rat.cpp', 'roach.cpp', 'rpg.cpp', + 'satchel.cpp', 'schedule.cpp', 'scientist.cpp', 'scripted.cpp', 'shotgun.cpp', 'singleplay_gamerules.cpp', 'skill.cpp', + 'sound.cpp', 'soundent.cpp', 'spectator.cpp', 'squadmonster.cpp', 'squeakgrenade.cpp', 'subs.cpp', + 'talkmonster.cpp', 'teamplay_gamerules.cpp', 'tempmonster.cpp', 'tentacle.cpp', + 'triggers.cpp', 'tripmine.cpp', 'turret.cpp', + 'util.cpp', + 'weapons.cpp', 'world.cpp', 'xen.cpp', 'zombie.cpp'] + + if bld.env.VOICEMGR: + source += bld.path.parent.ant_glob([ + 'game_shared/voice_gamemgr.cpp', + ]) + else: + defines += ['NO_VOICEGAMEMGR'] + + includes = Utils.to_list('. wpn_shared ../common ../engine ../pm_shared ../game_shared ../public') + + libs = [] + + if bld.env.DEST_OS == 'win32': + libname = bld.env.SERVER_NAME + '.dll' + elif bld.env.DEST_OS == 'linux': + libname = bld.env.SERVER_NAME + '.so' + elif bld.env.DEST_OS == 'darwin': + libname = bld.env.SERVER_NAME + '.dylib' + else: libname = '' + + bld.shlib( + source = source, + target = 'server', + features = 'c cxx', + includes = includes, + defines = defines, + use = libs, + install_path = os.path.join(bld.env.GAMEDIR, bld.env.SERVER_DIR, libname), + subsystem = bld.env.MSVC_SUBSYSTEM, + idx = 2 + ) diff --git a/scripts/waflib/deps.py b/scripts/waflib/deps.py new file mode 100644 index 00000000..f216515b --- /dev/null +++ b/scripts/waflib/deps.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# Michel Mooij, michel.mooij7@gmail.com + +from waflib import Utils +from waflib import Errors + + +def get_deps(bld, target): + '''Returns a list of (nested) targets on which this target depends. + + :param bld: a *waf* build instance from the top level *wscript* + :type bld: waflib.Build.BuildContext + :param target: task name for which the dependencies should be returned + :type target: str + :returns: a list of task names on which the given target depends + ''' + try: + tgen = bld.get_tgen_by_name(target) + except Errors.WafError: + return [] + else: + uses = Utils.to_list(getattr(tgen, 'use', [])) + deps = uses[:] + for use in uses: + deps += get_deps(bld, use) + return list(set(deps)) + + +def get_tgens(bld, names): + '''Returns a list of task generators based on the given list of task + generator names. + + :param bld: a *waf* build instance from the top level *wscript* + :type bld: waflib.Build.BuildContext + :param names: list of task generator names + :type names: list of str + :returns: list of task generators + ''' + tgens=[] + for name in names: + try: + tgen = bld.get_tgen_by_name(name) + except Errors.WafError: + pass + else: + tgens.append(tgen) + return list(set(tgens)) + + +def get_targets(bld): + '''Returns a list of user specified build targets or None if no specific + build targets has been selected using the *--targets=* command line option. + + :param bld: a *waf* build instance from the top level *wscript*. + :type bld: waflib.Build.BuildContext + :returns: a list of user specified target names (using --targets=x,y,z) or None + ''' + if bld.targets == '': + return None + targets = bld.targets.split(',') + for target in targets: + targets += get_deps(bld, target) + return targets + diff --git a/scripts/waflib/force_32bit.py b/scripts/waflib/force_32bit.py new file mode 100644 index 00000000..efec6b11 --- /dev/null +++ b/scripts/waflib/force_32bit.py @@ -0,0 +1,56 @@ +# encoding: utf-8 +# force_32bit.py -- force compiler to create 32-bit code +# Copyright (C) 2018 a1batross +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +from fwgslib import get_flags_by_compiler + +# Input: +# BIT32_MANDATORY(optional) -- fail if 32bit mode not available +# BIT32_ALLOW64(optional) -- ignore all checks, just set DEST_SIZEOF_VOID_P to 8 +# Output: +# DEST_SIZEOF_VOID_P -- an integer, equals sizeof(void*) on target + +def check_32bit(ctx, msg): + try: + ctx.check_cc( + fragment='''int main( void ) + { + int check[sizeof(void*) == 4 ? 1: -1]; + return 0; + }''', + msg = msg) + except ctx.errors.ConfigurationError: + return False + return True + +def configure(conf): + if getattr(conf.env, 'BIT32_ALLOW64'): + conf.env.DEST_SIZEOF_VOID_P = 8 + else: + if check_32bit(conf, 'Checking if \'{0}\' can target 32-bit'.format(conf.env.COMPILER_CC)): + conf.env.DEST_SIZEOF_VOID_P = 4 + else: + flags = ['-m32'] + # Think different. + if(conf.env.DEST_OS == 'darwin'): + flags = ['-arch', 'i386'] + env_stash = conf.env + conf.env.append_value('LINKFLAGS', flags) + conf.env.append_value('CFLAGS', flags) + conf.env.append_value('CXXFLAGS', flags) + if check_32bit(conf, '...trying with additional flags'): + conf.env.DEST_SIZEOF_VOID_P = 4 + else: + conf.env.DEST_SIZEOF_VOID_P = 8 + conf.env = env_stash + if getattr(conf.env, 'BIT32_MANDATORY') and conf.env.DEST_SIZEOF_VOID_P == 8: + conf.fatal('Compiler can\'t create 32-bit code!') diff --git a/scripts/waflib/fwgslib.py b/scripts/waflib/fwgslib.py new file mode 100644 index 00000000..e7cdee0d --- /dev/null +++ b/scripts/waflib/fwgslib.py @@ -0,0 +1,30 @@ +# encoding: utf-8 +# fwgslib.py -- utils for Waf build system by FWGS +# Copyright (C) 2018 a1batross +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +import os + +def get_flags_by_compiler(flags, compiler): + out = [] + if compiler in flags: + out += flags[compiler] + elif 'default' in flags: + out += flags['default'] + return out + +def get_flags_by_type(flags, type, compiler): + out = [] + if 'common' in flags: + out += get_flags_by_compiler(flags['common'], compiler) + if type in flags: + out += get_flags_by_compiler(flags[type], compiler) + return out diff --git a/scripts/waflib/msdev.py b/scripts/waflib/msdev.py new file mode 100644 index 00000000..df6b2ca9 --- /dev/null +++ b/scripts/waflib/msdev.py @@ -0,0 +1,774 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# Michel Mooij, michel.mooij7@gmail.com +# modified: Alibek Omarov, a1ba.omarov@gmail.com + +''' +Summary +------- +Exports and converts *waf* project data, for C/C++ programs, static- and shared +libraries, into **Microsoft Visual Studio**, also known as **msdev**, +project files (.vcproj) and solution (.sln) files. + +**Microsoft Visual Studio** is a mature and stable integrated development +environment for, amongst others, the C and C++ programming language. A free +version of this IDE, known as the *express* version can be obtained from Microsoft +at http://wwww.visualstudio.com. + +Description +----------- +When exporting *waf* project data, a single **Visual Studio** solution will be +exported in the top level directory of your *WAF* build environment. This +solution file will contain references to all exported **Visual Studio** +projects and will include dependencies between those projects and will have the +same name as APPNAME variable from the top level *wscript* file. + +For each single task generator (*waflib.TaskGenerator*), for instance a +*bld.program(...)* which has been defined within a *wscript* file somewhere in +the build environment, a single **Visual Studio** project file will be generated +in the same directory as where the task generator has been defined. +The name of this task generator will be used as name for the exported **Visual +Studio** project file. If for instance the name of the task generator is +*hello*, then a **Visual Studio** project file named *hello.vcproj* will be +exported. + +Example below presents an overview of an environment in which **Visual Studio** +files already have been exported:: + + . + ├── components + │ └── clib + │ ├── program + │ │ ├── cprogram.vcproj + │ │ └── wscript + │ ├── shared + │ │ ├── cshlib.vcproj + │ │ └── wscript + │ └── static + │ ├── cstlib.vcproj + │ └── wscript + │ + ├── waf.vcproj + ├── appname.sln + └── wscript + + +Projects will be exported such that they will use the same settings and +structure as has been defined for that build task within the *waf* build +environment as much as possible. Note that since cross compilation is not +really supported in this IDE, only the first environment encountered that +is targeted for **MS Windows** will be exported; i.e. an environment in +which:: + + bld.env.DEST_OS == 'win32' + +is true. + + +Please note that in contrast to a *normal* IDE setup the exported projects +will contain either a *debug* **or** a *release* build target but not both at +the same time. By doing so exported projects will always use the same settings +(e.g. compiler options, installation paths) as when building the same task in +the *waf* build environment from command line. + + +Usage +----- +**Visual Studio** project and workspace files can be exported using the *msdev* +command, as shown in the example below:: + + $ waf msdev + +When needed, exported **Visual Studio** project- and solution files can be +removed using the *clean* command, as shown in the example below:: + + $ waf msdev --clean + +Once exported simply open the *appname.sln* using **Visual Studio** +this will automatically open all exported projects as well. + +Tasks generators to be excluded can be marked with the *skipme* option +as shown below:: + + def build(bld): + bld.program(name='foo', src='foobar.c', msdev_skip=True) + +''' + +import os +import sys +import copy +import uuid +import shutil +import xml.etree.ElementTree as ElementTree +from xml.dom import minidom +from waflib import Utils, Logs, Errors, Context +from waflib.Build import BuildContext +# import waftools +# from waftools import deps +from deps import get_targets +from subproject import get_subproject_env + + +def options(opt): + '''Adds command line options to the *waf* build environment + + :param opt: Options context from the *waf* build environment. + :type opt: waflib.Options.OptionsContext + ''' + opt.add_option('--msdev', dest='msdev', default=False, action='store_true', help='select msdev for export/import actions') + opt.add_option('--clean', dest='clean', default=False, action='store_true', help='delete exported files') + + +def configure(conf): + '''Method that will be invoked by *waf* when configuring the build + environment. + + :param conf: Configuration context from the *waf* build environment. + :type conf: waflib.Configure.ConfigurationContext + ''' + pass + + +class MsDevContext(BuildContext): + '''export C/C++ tasks to MS Visual Studio projects and solutions.''' + cmd = 'msdev' + + def execute(self): + '''Will be invoked when issuing the *msdev* command.''' + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) + self.pre_build() + + for group in self.groups: + for tgen in group: + try: + f = tgen.post + except AttributeError: + pass + else: + f() + try: + self.get_tgen_by_name('') + except Exception: + pass + + self.msdev = True + if self.options.clean: + cleanup(self) + else: + export(self) + self.timer = Utils.Timer() + +def export(bld): + '''Exports all C and C++ task generators as **Visual Studio** projects + and creates a **Visual Studio** solution containing references to + those project. + + :param bld: a *waf* build instance from the top level *wscript*. + :type bld: waflib.Build.BuildContext + ''' + if not bld.options.msdev and not hasattr(bld, 'msdev'): + return + + Logs.pprint('RED', '''This tool is intended only to ease development for Windows-fags. +Don't use it for release builds, as it doesn't enables WinXP compatibility for now!''') + + solution = MsDevSolution(bld) + targets = get_targets(bld) + + saveenv = bld.env # root env + for tgen in bld.task_gen_cache_names.values(): + if targets and tgen.get_name() not in targets: + continue + if getattr(tgen, 'msdev_skipme', False): + continue + try: + bld.env = get_subproject_env(bld, tgen.path, True) + except IndexError: + bld.env = saveenv + if set(('c', 'cxx')) & set(getattr(tgen, 'features', [])): + project = MsDevProject(bld, tgen) + project.export() + + (name, fname, deps, pid) = project.get_metadata() + solution.add_project(name, fname, deps, pid) + + solution.export() + + +def cleanup(bld): + '''Removes all **Visual Studio** projects and workspaces from the + *waf* build environment. + + :param bld: a *waf* build instance from the top level *wscript*. + :type bld: waflib.Build.BuildContext + ''' + if not bld.options.msdev and not hasattr(bld, 'msdev'): + return + + targets = get_targets(bld) + saveenv = bld.env + + for tgen in bld.task_gen_cache_names.values(): + if targets and tgen.get_name() not in targets: + continue + if getattr(tgen, 'msdev_skipme', False): + continue + try: + bld.env = get_subproject_env(bld, tgen.path) + except IndexError: + bld.env = saveenv + if set(('c', 'cxx')) & set(getattr(tgen, 'features', [])): + project = MsDevProject(bld, tgen) + project.cleanup() + + solution = MsDevSolution(bld) + solution.cleanup() + + +class MsDev(object): + '''Abstract base class used for exporting *waf* project data to + **Visual Studio** projects and solutions. + + REMARK: + bld.objects() taks generators are treated as static libraries. + + :param bld: Build context as used in *wscript* files of your *waf* build + environment. + :type bld: waflib.Build.BuildContext + ''' + + PROGRAM = '1' + '''Identifier for projects containing an executable''' + + SHLIB = '2' + '''Identifier for projects containing a shared library''' + + STLIB = '4' + '''Identifier for projects containing a static library''' + + C = 'c' + '''Identifier for projects using C language''' + + CXX = 'cxx' + '''Identifier for projects using C++ language''' + + def __init__(self, bld): + self.bld = bld + + def export(self): + '''Exports a **Visual Studio** solution or project.''' + content = self.get_content() + if not content: + return + if self.xml_clean: + content = self.xml_clean(content) + + node = self.make_node() + if not node: + return + node.write(content) + Logs.pprint('YELLOW', 'exported: %s' % node.abspath()) + + def cleanup(self): + '''Deletes a **Visual Studio** solution or project file including + associated files (e.g. *.ncb*). + ''' + cwd = self.get_cwd() + for node in cwd.ant_glob('*.user'): + node.delete() + Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) + for node in cwd.ant_glob('*.ncb'): + node.delete() + Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) + for node in cwd.ant_glob('*.suo'): + node.delete() + Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) + for node in cwd.ant_glob('*.sln'): + node.delete() + Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) + node = self.find_node() + if node: + node.delete() + Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) + + def get_cwd(self): + cwd = os.path.dirname(self.get_fname()) + if cwd == "": + cwd = "." + return self.bld.srcnode.find_node(cwd) + + def find_node(self): + name = self.get_fname() + if not name: + return None + return self.bld.srcnode.find_node(name) + + def make_node(self): + name = self.get_fname() + if not name: + return None + return self.bld.srcnode.make_node(name.lower()) + + def get_fname(self): + ''' Returns file name.''' + return None + + def get_content(self): + ''' Returns file content.''' + return None + + def xml_clean(self, content): + s = minidom.parseString(content).toprettyxml(indent="\t") + lines = [l for l in s.splitlines() if not l.isspace() and len(l)] + lines[0] = '' + return '\n'.join(lines) + + +class MsDevSolution(MsDev): + '''Class used for exporting *waf* project data to a **Visual Studio** + solution located in the lop level directory of the *waf* build + environment. + + :param bld: Build context as used in *wscript* files of your *waf* build + environment. + :type bld: waflib.Build.BuildContext + ''' + + def __init__(self, bld): + super(MsDevSolution, self).__init__(bld) + self.projects = {} + self.xml_clean = None + + def get_fname(self): + '''Returns the workspace's file name.''' + return '%s.sln' % getattr(Context.g_module, Context.APPNAME) + + def export(self): + '''Exports a **Visual Studio** solution.''' + dst = self.get_fname() + + s = MSDEV_SOLUTION + + with open(dst, 'w') as f: + for line in s[0:3]: + f.write(line) + for name, (fname, deps, pid) in self.projects.items(): + sid = str(uuid.uuid4()).upper() + f.write('Project("{%s}") = "%s", "%s", "{%s}"\n' % (sid, name, fname, pid)) + if len(deps): + f.write('\tProjectSection(ProjectDependencies) = postProject\n') + for d in deps: + try: + (_, _, pid) = self.projects[d] + except KeyError: + pass + else: + f.write('\t\t{%s} = {%s}\n' % (pid, pid)) + f.write('\tEndProjectSection\n') + f.write('EndProject\n') + for line in s[3:8]: + f.write(line) + for _, (_, _, pid) in self.projects.items(): + f.write('\t\t{%s}.Debug|Win32.ActiveCfg = Debug|Win32\n' % (pid)) + f.write('\t\t{%s}.Debug|Win32.Build.0 = Debug|Win32\n' % (pid)) + for line in s[8:]: + f.write(line) + Logs.pprint('YELLOW', 'exported: %s' % os.path.abspath(dst)) + + def add_project(self, name, fname, deps, pid): + '''Adds a project to the workspace. + + :param name: Name of the project. + :type name: str + :param fname: Complete path to the project file + :type fname: str + :param deps: List of names on which this project depends + :type deps: list of str + ''' + self.projects[name] = (fname, deps, pid) + + +class MsDevProject(MsDev): + '''Class used for exporting *waf* project data to **Visual Studio** + projects. + + :param bld: Build context as used in *wscript* files of your *waf* build + environment. + :type bld: waflib.Build.BuildContext + + :param gen: Task generator that contains all information of the task to be + converted and exported to the **Visual Studio** project. + :type gen: waflib.Task.TaskGen + ''' + + def __init__(self, bld, gen): + super(MsDevProject, self).__init__(bld) + self.gen = gen + self.id = str(uuid.uuid4()).upper() + self.type = self.get_type(gen) + self.language = self.get_language(gen) + self.buildpath = self.get_buildpath(bld, gen) + + def get_type(self, gen): + if set(('cprogram', 'cxxprogram')) & set(gen.features): + return MsDev.PROGRAM + elif set(('cshlib', 'cxxshlib')) & set(gen.features): + return MsDev.SHLIB + else: + return MsDev.STLIB + + def get_language(self, gen): + return MsDev.CXX if 'cxx' in gen.features else MsDev.C + + def get_buildpath(self, bld, gen): + pth = '%s/%s' % (bld.path.get_bld().path_from(gen.path), gen.path.relpath()) + return pth.replace('/', '\\') + + def get_fname(self): + '''Returns the project's file name.''' + return '%s/%s.vcproj' % (self.gen.path.relpath().replace('\\', '/'), self.gen.get_name()) + + def get_root(self): + '''Returns a document root, either from an existing file, or from template.''' + fname = self.get_fname() + if os.path.exists(fname): + tree = ElementTree.parse(fname) + root = tree.getroot() + else: + root = ElementTree.fromstring(MSDEV_PROJECT) + return root + + def get_content(self): + '''Returns the content of a project file.''' + root = self.get_root() + root.set('Name', self.gen.get_name()) + root.set('ProjectGUID', '{%s}' % self.id) + configurations = root.find('Configurations') + for configuration in configurations.iter('Configuration'): + configuration.set('ConfigurationType', '%s' % self.type) + configuration.set('OutputDirectory', '%s\\msdev' % self.buildpath) + configuration.set('IntermediateDirectory', '%s\\msdev' % self.buildpath) + for tool in configuration.iter('Tool'): + name = tool.get('Name') + if name == 'VCCLCompilerTool': + tool.set('PreprocessorDefinitions', '%s' % self.get_compiler_defines(self.gen)) + includes = [] + for include in self.get_compiler_includes(self.bld, self.gen): + includes.append('%s' % include) + tool.set('AdditionalIncludeDirectories', ';'.join(includes)) + if name == 'VCLinkerTool': + if self.type == MsDev.PROGRAM: + # Force Windows Subsystem + # TODO: this isn't enables Windows XP compatibility! + tool.set('SubSystem', '2') + self.update_link_deps(tool) + self.update_link_paths(tool) + files = root.find('Files') + self.update_includes(files) + self.update_sources(files) + return ElementTree.tostring(root) + + def update_includes(self, files): + '''Add include files.''' + includes = [] + for filtr in files.iter('Filter'): + if filtr.get('Name') == 'Header Files': + for include in filtr.iter('File'): + includes.append(include.get('RelativePath')) + break + if len(includes) == 0: + filtr = ElementTree.SubElement(files, 'Filter', attrib={'Name':'Header Files', 'Filter':'h;hpp;hxx;hm;inl;inc;xsd'}) + filtr.set('UniqueIdentifier', '{%s}' % str(uuid.uuid4()).upper()) + for include in self.get_include_files(self.bld, self.gen): + if include not in includes: + ElementTree.SubElement(filtr, 'File', attrib={'RelativePath':'%s' % include}) + + def update_sources(self, files): + '''Add source files.''' + sources = [] + for filtr in files.iter('Filter'): + if filtr.get('Name') == 'Source Files': + for source in filtr.iter('File'): + sources.append(source.get('RelativePath')) + break + if len(sources) == 0: + filtr = ElementTree.SubElement(files, 'Filter', attrib={'Name':'Source Files', 'Filter':'cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx'}) + filtr.set('UniqueIdentifier', '{%s}' % str(uuid.uuid4()).upper()) + for source in self.get_genlist(self.gen, 'source'): + if source not in sources: + ElementTree.SubElement(filtr, 'File', attrib={'RelativePath':'%s' % source}) + + def update_link_deps(self, tool): + '''Add libraries on which this project depends.''' + deps = tool.get('AdditionalDependencies') + + deps = [] # clean out deps everytime + + libs = self.get_link_libs(self.bld, self.gen) + for lib in libs: + dep = '%s.lib' % lib + if dep not in deps: + deps.append(dep) + if len(deps): + add_deps = " ".join(deps) # work around when converting to vcxproj by inserting spaces + tool.set('AdditionalDependencies', add_deps) + + def update_link_paths(self, tool): + deps = tool.get('AdditionalLibraryDirectories', '') + deps = [] + dirs = self.get_link_paths(self.bld, self.gen) + for dep in dirs: + if dep not in deps: + deps.append(dep) + if len(deps): + tool.set('AdditionalLibraryDirectories', ';'.join(deps)) + + def get_metadata(self): + '''Returns a tuple containing project information (name, file name and + dependencies). + ''' + name = self.gen.get_name() + fname = self.get_fname().replace('/', '\\') + deps = Utils.to_list(getattr(self.gen, 'use', [])) + return (name, fname, deps, self.id) + + def get_genlist(self, gen, name): + lst = Utils.to_list(getattr(gen, name, [])) + lst = [str(l.path_from(gen.path)) if hasattr(l, 'path_from') else l for l in lst] + return [l.replace('/', '\\') for l in lst] + + def get_compiler_options(self, bld, gen): + if self.language == MsDev.CXX: + flags = getattr(gen, 'cxxflags', []) + bld.env.CXXFLAGS + else: + flags = getattr(gen, 'cflags', []) + bld.env.CFLAGS + if self.type == MsDev.SHLIB: + if self.language == MsDev.CXX: + flags.extend(bld.env.CXXFLAGS_cxxshlib) + else: + flags.extend(bld.env.CFLAGS_cshlib) + return list(set(flags)) + + def get_compiler_includes(self, bld, gen): + includes = self.get_genlist(gen, 'includes') + for include in bld.env['INCLUDES']: + root = bld.path.abspath().replace('\\', '/') + pref = os.path.commonprefix([root, include]) + if pref == root: + node = bld.root.find_dir(include) + if node: + includes.append(node.path_from(gen.path).replace('/', '\\')) + + deps = Utils.to_list(getattr(gen, 'use', [])) + for dep in deps: + uselib_incs = bld.env['INCLUDES_%s' % dep] + for uselib_inc in uselib_incs: + root = bld.root.abspath().replace('\\', '/') + pref = os.path.commonprefix([root, uselib_inc]) + if pref == root: + node = bld.root.find_dir(uselib_inc) + if node: + inc = node.path_from(gen.path).replace('/', '\\') + includes.append(inc) + Logs.pprint('YELLOW', 'Added relative include: %s' % inc) + includes.append(uselib_inc) + return includes + + def get_compiler_defines(self, gen): + defines = self.get_genlist(gen, 'defines') + gen.bld.env.DEFINES + if 'win32' in sys.platform: + defines = [d.replace('"', '\\"') for d in defines] + defines = ';'.join(defines) + return defines + + def get_link_options(self, bld, gen): + flags = getattr(gen, 'linkflags', []) + bld.env.LINKFLAGS + if self.language == MsDev.CXX: + if self.type == MsDev.SHLIB: + flags.extend(bld.env.LINKFLAGS_cxxshlib) + else: + flags.extend(bld.env.LINKFLAGS_cshlib) + return list(set(flags)) + + def get_link_libs(self, bld, gen): + libs = Utils.to_list(getattr(gen, 'lib', [])) + deps = Utils.to_list(getattr(gen, 'use', [])) + for dep in deps: + try: + tgen = bld.get_tgen_by_name(dep) + except Errors.WafError: + uselib_libs = bld.env['LIB_%s' % dep] + for uselib_lib in uselib_libs: + libs.append(uselib_lib) + pass + else: + if self.type == MsDev.STLIB: + libs.append(dep) + return libs + + def get_link_paths(self, bld, gen): + dirs = [] + deps = Utils.to_list(getattr(gen, 'use', [])) + for dep in deps: + try: + tgen = bld.get_tgen_by_name(dep) + except Errors.WafError: + uselib_paths = bld.env['LIBPATH_%s' % dep] + for uselib_path in uselib_paths: + root = bld.root.abspath().replace('\\', '/') + pref = os.path.commonprefix([root, uselib_path]) + if pref == root: + node = bld.root.find_dir(uselib_path) + if node: + libpath = node.path_from(gen.path).replace('/', '\\') + dirs.append(libpath) + Logs.pprint('YELLOW', 'Added relative library path: %s' % libpath) + dirs.append(uselib_path) + pass + else: + if self.type in (MsDev.STLIB, MsDev.SHLIB): + directory = '%s\\msdev' % tgen.path.get_bld().path_from(gen.path) + if directory not in dirs: + dirs.append(directory.replace('/', '\\')) + elif self.type in (MsDev.PROGRAM): + for directory in tgen.lib_paths: + if directory not in dirs: + dirs.append(directory.replace('/', '\\')) + return dirs + + def get_include_files(self, bld, gen): + includes = [] + for include in self.get_genlist(gen, 'includes'): + node = gen.path.find_dir(include) + if node: + for header in node.ant_glob('*.h*'): + includes.append(header.path_from(gen.path).replace('/', '\\')) + + for include in bld.env['INCLUDES']: + root = bld.path.abspath().replace('\\', '/') + pref = os.path.commonprefix([root, include]) + if pref == root: + node = bld.root.find_dir(include) + if node: + for header in node.ant_glob('*.h*'): + includes.append(header.path_from(gen.path).replace('/', '\\')) + + return includes + + +MSDEV_PROJECT = \ +''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +''' + +MSDEV_SOLUTION = [ +'Microsoft Visual Studio Solution File, Format Version 8.00\n', +'# Visual Studio 2005\n', +'Global\n', + 'GlobalSection(SolutionConfigurationPlatforms) = preSolution\n', + 'Debug|Win32 = Debug|Win32\n', + 'EndGlobalSection\n', + 'GlobalSection(ProjectConfigurationPlatforms) = postSolution\n', + 'EndGlobalSection\n', + 'GlobalSection(SolutionProperties) = preSolution\n', + 'HideSolutionNode = FALSE\n', + 'EndGlobalSection\n', +'EndGlobal\n', +'\n'] diff --git a/scripts/waflib/reconfigure.py b/scripts/waflib/reconfigure.py new file mode 100644 index 00000000..333e64ac --- /dev/null +++ b/scripts/waflib/reconfigure.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Copyright (c) 2019 mittorn + +''' +Reconfigure + +Store/load configuration user input + +Usage: + def options(opt): + opt.load('reconfigure') + + def configure(conf): + conf.load('reconfigure') + + ./waf configure --reconfigure +''' + +from waflib import Configure, Logs, Options, Utils, ConfigSet +import os + +import optparse +STORE_PATH = 'build/configuration.py' + +def options(opt): + opt.add_option('--rebuild-cache', dest='rebuild_cache', default=False, action='store_true', help='load previous configuration') + opt.add_option('--reconfigure', dest='reconfigure', default=False, action='store_true', help='load and update configuration') + +def configure(conf): + store_data = ConfigSet.ConfigSet() + options = vars(conf.options) + environ = conf.environ + if conf.options.reconfigure or conf.options.rebuild_cache: + store_data.load(STORE_PATH) + if conf.options.reconfigure: + for o in options: + if options[o]: store_data['OPTIONS'][o] = options[o] + store_data['ENVIRON'].update(environ) + store_data.store(STORE_PATH) + conf.environ = store_data['ENVIRON'] + conf.options = optparse.Values(store_data['OPTIONS']) + else: + store_data['OPTIONS'] = vars(conf.options) + store_data['ENVIRON'] = conf.environ + store_data.store(STORE_PATH) + \ No newline at end of file diff --git a/scripts/waflib/xcompile.py b/scripts/waflib/xcompile.py new file mode 100644 index 00000000..71d05ca6 --- /dev/null +++ b/scripts/waflib/xcompile.py @@ -0,0 +1,208 @@ +# encoding: utf-8 +# xcompile.py -- crosscompiling utils +# Copyright (C) 2018 a1batross +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +from fwgslib import get_flags_by_compiler +import os +import sys + +# Output: +# CROSSCOMPILING -- set to true, if crosscompiling is enabled +# DEST_OS2 -- as some operating systems is built on top of another, it's better to not change DEST_OS, +# instead of this DEST_OS2 is defined with target value +# For example: android is built on top of linux and have many things in common, +# but it can't be considered as default GNU/Linux. +# Possible values: +# DEST_OS2 DEST_OS +# 'android' 'linux' + +class Android: + arch = None + toolchain = None + api = None + toolchain_path = None + ndk_home = None + + # TODO: New Android NDK support? + # TODO: Crystax support? + # TODO: Support for everything else than linux-x86_64? + # TODO: Determine if I actually need to implement listed above + + def is_arm(self): + ''' + Checks if selected architecture is **32-bit** ARM + ''' + return self.arch.startswith('armeabi') + + def is_x86(self): + ''' + Checks if selected architecture is **32-bit** or **64-bit** x86 + ''' + return self.arch.startswith('x86') + + def is_arm64(self): + ''' + Checks if selected architecture is AArch64 + ''' + return self.arch == 'aarch64' + + def is_clang(self): + ''' + Checks if selected toolchain is Clang (TODO) + ''' + return self.toolchain.startswith('clang') + + def is_hardfp(self): + return self.arch.endswith('-hard') + + def gen_toolchain_path(self): + path = 'toolchains' + if self.is_clang(): + raise Exception('Clang is not supported yet') + else: + if self.is_x86(): + toolchain_folder = self.arch + '-' + self.toolchain + elif self.is_arm(): + toolchain_folder = 'arm-linux-androideabi-' + self.toolchain + else: + toolchain_folder = self.arch + '-linux-android-' + self.toolchain + + if sys.platform.startswith('linux'): + toolchain_host = 'linux' + elif sys.platform.startswith('darwin'): + toolchain_host = 'darwin' + elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): + toolchain_host = 'windows' + else: raise Exception('Unsupported by NDK host platform') + + toolchain_host += '-' + + # Assuming we are building on x86 + if sys.maxsize > 2**32: + toolchain_host += 'x86_64' + else: toolchain_host += 'x86' + + if self.arch == 'x86': + triplet = 'i686-linux-android-' + elif self.is_arm(): + triplet = 'arm-linux-androideabi-' + else: + triplet = self.arch + '-linux-android-' + + return os.path.join(path, toolchain_folder, 'prebuilt', toolchain_host, 'bin', triplet) + + def cc(self): + return os.path.abspath(os.path.join(self.ndk_home, self.toolchain_path + 'gcc')) + + def cxx(self): + return os.path.abspath(os.path.join(self.ndk_home, self.toolchain_path + 'g++')) + + def system_stl(self): + # TODO: proper STL support + return os.path.abspath(os.path.join(self.ndk_home, 'sources', 'cxx-stl', 'system', 'include')) + + def sysroot(self): + arch = self.arch + if self.is_arm(): + arch = 'arm' + elif self.is_arm64(): + arch = 'arm64' + path = 'platforms/android-{0}/arch-{1}'.format(self.api, arch) + + return os.path.abspath(os.path.join(self.ndk_home, path)) + + def cflags(self): + cflags = ['--sysroot={0}'.format(self.sysroot()), '-DANDROID', '-D__ANDROID__'] + cflags += ['-I{0}'.format(self.system_stl())] + if self.is_arm(): + if self.arch.startswith('armeabi-v7a'): + # ARMv7 support + cflags += ['-mthumb', '-mfpu=neon', '-mcpu=cortex-a9', '-mvectorize-with-neon-quad', '-DHAVE_EFFICIENT_UNALIGNED_ACCESS', '-DVECTORIZE_SINCOS'] + if self.arch == 'armeabi-v7a-hard': + cflags += ['-D_NDK_MATH_NO_SOFTFP=1', '-mhard-float', '-mfloat-abi=hard', '-DLOAD_HARDFP', '-DSOFTFP_LINK'] + else: + cflags += ['-mfloat-abi=softfp'] # Tegra 2 sucks + else: + # ARMv5 support + cflags += ['-march=armv5te', '-mtune=xscale', '-msoft-float'] + elif self.is_x86(): + cflags += ['-mtune=atom', '-march=atom', '-mssse3', '-mfpmath=sse', '-DVECTORIZE_SINCOS', '-DHAVE_EFFICIENT_UNALIGNED_ACCESS'] + return cflags + + def ldflags(self): + ldflags = ['--sysroot={0}'.format(self.sysroot())] + if self.is_arm(): + if self.arch.startswith('armeabi-v7a'): + ldflags += ['-march=armv7-a', '-Wl,--fix-cortex-a8'] + if self.arch == 'armeabi-v7a-hard': + ldflags += ['-Wl,--no-warn-mismatch', '-lm_hard'] + else: + ldflags += ['-march=armv5te'] + return ldflags + + def __init__(self, ndk_home, arch, toolchain, api): + self.ndk_home = ndk_home + self.arch = arch + self.toolchain = toolchain + self.api = api + self.toolchain_path = self.gen_toolchain_path() + +def options(opt): + android = opt.add_option_group('Android options') + android.add_option('--android', action='store', dest='ANDROID_OPTS', default=None, + help='enable building for android, format: --android=,,, example: --android=armeabi-v7a-hard,4.9,9') + +def configure(conf): + if conf.options.ANDROID_OPTS: + for i in ['ANDROID_NDK_HOME', 'ANDROID_NDK']: + android_ndk_path = os.getenv(i) + if android_ndk_path != None: + break + + if not android_ndk_path: + conf.fatal('Set ANDROID_NDK_HOME environment variable pointing to the root of Android NDK!') + + values = conf.options.ANDROID_OPTS.split(',') + if len(values) != 3: + conf.fatal('Invalid --android paramater value!') + + valid_archs = ['x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'armeabi-v7a-hard', 'aarch64', 'mipsel', 'mips64el'] + + if values[0] not in valid_archs: + conf.fatal('Unknown arch: {0}. Supported: {1}'.format(values[0], ', '.join(valid_archs))) + + android = Android(android_ndk_path, values[0], values[1], values[2]) + conf.options.ALLOW64 = True # skip pointer length check + conf.options.NO_VGUI = True # skip vgui + conf.options.NANOGL = True + conf.options.GLWES = True + conf.options.GL = False + conf.environ['CC'] = android.cc() + conf.environ['CXX'] = android.cxx() + conf.env.CFLAGS += android.cflags() + conf.env.CXXFLAGS += android.cflags() + conf.env.LINKFLAGS += android.ldflags() + + conf.env.HAVE_M = True + if android.is_hardfp(): + conf.env.LIB_M = ['m_hard'] + else: conf.env.LIB_M = ['m'] + + conf.msg('Selected Android NDK', android_ndk_path) + # no need to print C/C++ compiler, as it would be printed by compiler_c/cxx + conf.msg('... C/C++ flags', ' '.join(android.cflags()).replace(android_ndk_path, '$NDK')) + conf.msg('... linker flags', ' '.join(android.ldflags()).replace(android_ndk_path, '$NDK')) + + # conf.env.ANDROID_OPTS = android + conf.env.DEST_OS2 = 'android' +# else: +# conf.load('compiler_c compiler_cxx') # Use host compiler :) diff --git a/waf b/waf new file mode 100755 index 00000000..7066d9f3 --- /dev/null +++ b/waf @@ -0,0 +1,170 @@ +#!/usr/bin/env python +# encoding: latin-1 +# Thomas Nagy, 2005-2018 +# +""" +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +import os, sys, inspect + +VERSION="2.0.15" +REVISION="ff6573b86ad5ff5d449c8852ad58b8bc" +GIT="02c9f814da0d3f3cd4c1a4f9c5e0c7ed7129bb19" +INSTALL='' +C1='#/' +C2='#,' +C3='#$' +cwd = os.getcwd() +join = os.path.join + + +WAF='waf' +def b(x): + return x +if sys.hexversion>0x300000f: + WAF='waf3' + def b(x): + return x.encode() + +def err(m): + print(('\033[91mError: %s\033[0m' % m)) + sys.exit(1) + +def unpack_wafdir(dir, src): + f = open(src,'rb') + c = 'corrupt archive (%d)' + while 1: + line = f.readline() + if not line: err('run waf-light from a folder containing waflib') + if line == b('#==>\n'): + txt = f.readline() + if not txt: err(c % 1) + if f.readline() != b('#<==\n'): err(c % 2) + break + if not txt: err(c % 3) + txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00')) + + import shutil, tarfile + try: shutil.rmtree(dir) + except OSError: pass + try: + for x in ('Tools', 'extras'): + os.makedirs(join(dir, 'waflib', x)) + except OSError: + err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir) + + os.chdir(dir) + tmp = 't.bz2' + t = open(tmp,'wb') + try: t.write(txt) + finally: t.close() + + try: + t = tarfile.open(tmp) + except: + try: + os.system('bunzip2 t.bz2') + t = tarfile.open('t') + tmp = 't' + except: + os.chdir(cwd) + try: shutil.rmtree(dir) + except OSError: pass + err("Waf cannot be unpacked, check that bzip2 support is present") + + try: + for x in t: t.extract(x) + finally: + t.close() + + for x in ('Tools', 'extras'): + os.chmod(join('waflib',x), 493) + + if sys.hexversion<0x300000f: + sys.path = [join(dir, 'waflib')] + sys.path + import fixpy2 + fixpy2.fixdir(dir) + + os.remove(tmp) + os.chdir(cwd) + + try: dir = unicode(dir, 'mbcs') + except: pass + try: + from ctypes import windll + windll.kernel32.SetFileAttributesW(dir, 2) + except: + pass + +def test(dir): + try: + os.stat(join(dir, 'waflib')) + return os.path.abspath(dir) + except OSError: + pass + +def find_lib(): + src = os.path.abspath(inspect.getfile(inspect.getmodule(err))) + base, name = os.path.split(src) + + #devs use $WAFDIR + w=test(os.environ.get('WAFDIR', '')) + if w: return w + + #waf-light + if name.endswith('waf-light'): + w = test(base) + if w: return w + err('waf-light requires waflib -> export WAFDIR=/folder') + + dirname = '%s-%s-%s' % (WAF, VERSION, REVISION) + for i in (INSTALL,'/usr','/usr/local','/opt'): + w = test(i + '/lib/' + dirname) + if w: return w + + #waf-local + dir = join(base, (sys.platform != 'win32' and '.' or '') + dirname) + w = test(dir) + if w: return w + + #unpack + unpack_wafdir(dir, src) + return dir + +wafdir = find_lib() +sys.path.insert(0, wafdir) + +if __name__ == '__main__': + + from waflib import Scripting + Scripting.waf_entry_point(cwd, VERSION, wafdir) + +#==> +#BZh91AY&SYÑðR½TØÿÿÿ´Ðÿÿÿÿÿÿÿÿÿÿÿu  ƒ¬00Á˜0€(bÜ÷½¶w#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$¾Þ}:æÛS}pªr·°7b4×ÛC—ÛvÓµíÔºÚÑ67£R¤í¢D´äû‚×µ]µí×dÐXÔóÏ«ïœ wÜí½svÈä¡¥%½žÝÞ‚µ-µÐbîãÛ1Ö÷½ÁRß|ÎVO]EçºðYî•Ôûxr{ µ®ì÷½÷ßwß°<öøÞø×o¾Û^]¸¾æòÆ÷uÎ8#$ô#$#$ `#$xôz=<<”ÜP)ݳEµ:7w>Ž¯i=ÃUvi@F…:ÎÖÝÛ}:#$t÷°'`èä((m”(:0#/*”¢ŠvEJQ$#$Ð=®‘@•*®÷^¶{ë=½õÓop½%ÞÉŒ—{®în³)³§J•²u‰Jm×WÜõshõÔàw}¾×ZóÛ=·­ÊÞçZ÷½qRvÞöôööÍmï4}íŸfìÓ“Þ;)íõϽœÛËv¾÷Ñï}îûì«ÓU66ÕÙARBú`úzr®„¶Îö{̺ë7w{Ï]Ï\$¡ËwœŽÃÉ9´Ä¥Zwyø4#$J*’OCžºP½ÏO%4ÝãµÑuµ·n½†I>àwzÕñ÷nûŸ@dm….˜¥­­uÝ6¾1l·ÖQ°ùÝçx#$^íïP;xíö3w·žû{}uá_ö2`æ>ëhQkO¾÷x–›»jœkŸGD¥ž³Ìøûß^ZnÅ÷½{mz›¦ã;±÷¼Öé&Þ8»Ù§[eÞï¯>¼åô¥±E°h/®k¹×ßxå»2ìøL½³ÒòÂ…=í®KºÝ=·o¾)zÖΰ´OŸf½»³m¬Þìûc¯4Ùº>´÷·rÞÖç5VO^ìáìröðw·.œÕ½Þ¯n/`í\÷^w§]÷¼Ø}Ûàé\Ž¤ %Rгæ0d6ld¦Ù»«ì«t»Ûzó.3»6Põ81ÜÑ+®Ø¼ð÷²“k×f÷GBõž´Û¶åà#$ jÚ #$÷«—.®ó²‹Ž™Í{e´Û½ÎœŸlwÜa÷®›9HáÜ΂yÌ»e+ß}ÁÉæ÷nTÓê¹fÔçDA½¸õçu¯v<Û¾|w{{Û®›à2Z ¡ÛÜ°ö5լ̽Ñæª@÷²õ«Ò'¹òùö=ów书·»Ý½Ýݼw;HmôÙß{[ºçŧ¦Ç¹N7kœç …j[[(z/w¶ôeÛxïr0VØ6Uqã:^µkfðí­Öﶧ>}ˆ#$#½—#,USNÞ÷½©£Ó»£ƒ»nõ\ûºûTï2ïŽÕÓ«Üú|Í°«¯vfì/{}Ï»Åösn’ lR({y›zoZÛÒðÜ:­0,§}ã¼óÇÍö}o @hhR{3p#$UÇ•yÜï¾$ºl4#/¥žÎöKݸÒ¬œÛ…ÙÝÝœ în%U¶î›m7vƒwPU0Ø»iɪN»¶éîõÒû½í#/¯>êoL^Ó;=ÀMvNóºBczåÞž•z—rÎw,¿ÎuçÚë3š¹›…B˜ˆM^,Ñ2©Ù.e•) I„˜šlK]‹ ìcHÎ £».Ô2ø·,Œ¯MÍ#,’0ÄÅâà Š k{—¯ýË,?¹€nᯛۙ¢4Yòt\×ɯ&âvPR’(±b‚>ÿú”[”;žLVGµèØŠ)†Ú‹',•ö9’,Æ“ßÌl hlO5Rg„?³räúcG› G H!08˜q%òþ‡ÏýÛF[1Ý< •HuM¿Whc ½¾,A­ZÙdcÏnóºòŒs—EÜS+›t²Š¹·O;ˆ“cb}w_)­âÑ¢,ü}Õó¯Ê¯Ø·"™_"Û—!þ‹vÕã—7ÏÀˆKýó=í<™b#6ÌziÙÆÌk}žv×»Ùì÷U\¤Ú3ºåã×iÎãÂHˆÃz”eaÛÐÞ âk®WyÝÊ:W.d£.»¤‘Îd/µ­¼¼êÿbþ…Þ_DÕ(V)BŠ‘¦†wmŒºdâ2Õ‹}”R¢~—cj~§¦$2ðI.þŸ\¾*ú}ý^¡RzíE^© }x•³ù&¬ÂJ\ ﯳ8æŽÇCïβhÐìmð´SïŠytªùóöüjΫÙw¶×$Š Êh~-H¨¡F.%™‹Ž¶V[ÇCƒ#,hj¸2ÝFRrugjhÉÀM’_:ö]pfY™Xçüö¼ ÷ЇŔƒÊª)O‡_¶ýó¾¦rvîÖéɯB’"ÆÒ2…‘±•;“tÎAI£F…y&,¥:²Úl^”?ËókÓiĦ¢“áݸn#$(5£=VFmìÓ#1épJ.kšŠØ¼ïÙÞ½^D ¥Y*÷rÆ¢¿T·^îÇ­±dŠ#/ŒãFšâZ•T-ÅÔl›|ϺÞ1¨4–ûA™C…± xÞº±ÎÅÂ/”)½%E©Q:Ô–ãPåÌ Â#™­lÕŸ‚I„V~˳íënÊɱ_Wu_ÆèZI\÷²ðÑ$ZA`°Õ¶K ¤i(bÒC‹i¶¤ZÓ‰¡ëGƒ¶éE2„R]U¥"»wÕ¬ýUjxiK¿…e99eéÝeƒQ€§ŠÙ†¢œ8Ä1Š>ð± –…¶(ÑÝ¢4¶ÒÓV¾Ô¥ÝDÙè„_™„íÚ…i¶ŠÄêÃÍ–±ä¥ÑÒŠœ£Â©æüT{8:nÎ8º9ƒlXŽ‹ µË½ß2Ãq—ÙýP÷gzˆrõNüÀÆ5ÚC›¬0âMöT«¶³,3ÂË( Œb´fF”ß³ÜÌ}}í<ÓuÕÊdŸýfoÓðó€o¼ï3» ~é#åªi”"=í'”Ö¾ê£ô÷r³átpvWs'‡¯Wìш[hS“š÷Óo=R’\‰crF“MÏe‡×–ìƒ6q¸-H~I®ï2é°GÆ.]Ž¤AKƒ™S—<*J*¼(x{nrp¢rhû™B©úyß<|e‚D&˜gFÏÖë°µæø—_,q\—Í:¡g}–8ç–W<{*Cݶ…Æ q‡ÎöÒDcîH'›#,^óàÂÒZM¨´,>³¶ pÈÍRßi#v/P½}#Ç…œáÇ–tÊ©~#,-ÐÖ6¡õ«Løü¹í§Ö“:…^éKsYÃ.FÜðÖ=½åQäøªF‡õÌvG®ØcÀÑÖãz…U¨ÃÛ2‘ž>©[å¶Ò„˜p"Gû>—}©™nµÛ+jqðï×J]\t莑G×ÅɧðˆÖ“¯DezÀôQLŽ¢P¤Õ53ÃJºª‹:íƒtFóuƒvC•Ää#×Ç)'q¦”§E;yÎè™ù&?,¿žÕ3†1O}aNßçz<¶Ÿ'Ókðò¢Ûï9›õáH#>Œ)f©ÃaëR„wßlNðß@½)£¥­WÿtW–FnM´B8÷8»h¸×©Ûº†ä1žgY†Ùìé m±ÏËt÷4k˜yk¯žÖ›ï1×d$’DX |y…O^T¥=.bÀCý1“J4±é/±õ5¦O½TG§/Ho©ß¬¯eyï”×iUñ(¦/.ú¦¡ŒNñP:c²c¶œ%xr„@©#,§w9V;ÊÖÜkîÑz¬ÆÛ&Ç×®«,‚cȶ_Ê/‹4þ­ø;íœÍjvײ™ϳÃ!²¢*n“í“êïçï×[7åЉ*U“!VT­°¾Ö…›J+¹]zî§ÐÜe÷zºšÒ{®‹#,õ¹~- UKTWý–¢¤&|¯ü·_‹ø¼ëióü{¯RWÞÔWÞÃíKb"¤øÑVŠ#AEöT¦|Ùê'ãÛ›¥ªßJ Vä=,5úÙ•Ÿ[úùÏF(/«r²HŸÍ­µ}pÝoUèÔ5F»,¤ïUMD#,q=ð3ÙïÊõyyÎZÖ³KY1„û2ÖïHi™øB«ç|ÏpÐë°`7á5òœÕ>ÄêàY†¢sl«DùÖ%Î/‡ScmdývñüÑp3ä$Æs‹=d.©|d[Κwçt5`r`QöÑH¨¯çL ß³7:)x«1H²0¤çW~#,ZTÒ©ðÜÑŒùtuO³~y¾$_²Î抠Êsß¾4?¢-:ŸG»BF/£_A#,¯Æf½#,­ÛX)?)§ëq6œN¹ÚfAuôò“å]!¶P“ †ÕÁß2•À® ŒTSòe1¶¸µ987ðîËÚñ¤iši5¯,ühz‡ÐÀ¾Ú¤x3[…=;6¹‡ä—¶,/Z-€Š±%x^‘šDES#/‡‡ñJ m쪤<|À¤uNí+ê•ãE3’R“Jé{4}'k2C<"Tm¶³ìª¦ÞHóÛh5ÑêÈã¼ÔVm ð§g‹ˆ|ïK5x2#,ƒÒ¡À@¿cFì¥HˆÅé@R-¯¦9r¬èœlÿf´xð¨#/h6ÀêD´ðaK–R‚±7gFTaes×^¾o#,‘Ò÷àbì±):2É»ûÎû#T/\5‘~þõÇ$o…ÑEÿlC㉾=òUDõ"gÏPÞoÑÉü»2ü*mg}è–‰àøC›éwÏγŒk@‘‰¢RáɬE£[³±ê'ÿ®ázw\îó®wã™2‚ð;U°Ø¥”cO»8¹>¡ÖºUpCÄùòôìòؼž±D#/s º>~½xƒ5 #,¥ÛöÀ‡ŒëI ÛLj¡W.’¢ V­ãYPîz¡å½q‚écm\p­¾"š“¡¯¯ZºÊ[öÔþžTÊp¨CN¿‡JAQ’8dr*¾¤?½ÇWìdÛëB­;bŒ8õ¢[v>wNšÛ­bœ6¢<ìcy–—×áWŽhI—šZnÆ߯=÷ãt°\½ŽîÙÍûjƒ‹•ODóײôsîazL¼FžJÊkAì›÷ªE''Ni<·XôD}¡*¼Áq½Él‚Sòy ÙXoÎïG·o›Å‰líã^Aæ“g^²V¸³^¹©zÿ-}¸<(ñf`¨Åˆ³øtͽ‰UQ9c:ªLŠº]ó£áÙÈ?Vu*Ìe3âÔ#,¨‡Õ9!ø÷VìÔñÖ‹Gaš-íts¬CMd±#OzģС.|¨^6ŸåP¶u\dœ#ú4­\þŸve÷í&Pn‡Dä7Þ(ùb&¸ ÆF=ªDlÃø³}7€D#æÎ[_M±Ö1aújÖã¬K‡”8ª_ʧ5¿Ã8µ*5JæÑC7mDüÔ¤—œÌo|¹™ÇôîÌu© ܽ Pm´ÆÆ6½ì÷ì'}E~NçßlŸ¥ÐYŒ‚ØÏžü~š??¾€ÇZ;^õgšZ'ܬÆ'$´ç¯Àïç]Ÿ$îïàPºT7ìç rtƪÓ~ÐG]ŸÉ²cá¼Î¶¸¥åp«5)慎bkIQ~#,Z#/Êì–Íö£vÛiÎð7N ›hÄe hP"1b±ò&0b¦¶Öq‹⬠.…ìÔê”ÌUçˆri™a_™®‚|Ý:d³É‡h00Y½UDà’Ƭ…kUΩ‰…ÇEŽé)¡g½Ü‰ÛÉãhžª„ §²±ªÃÇš¯‡ª¥ÎôZçk=9uï—BŒL“£ò&3®k1µè‘s­_Å•äZD£b‰šõäí¨z Ú6ø{mû#˜ÊÑ°Þ9˜¤:4-×… Gæ#/±÷ãv™QƒI…°?ƒ¸Èóö*£ÄÖjŠ‰¯æL… <C*5š¨piS£1œZ$»¨zÝj”ˆÌÔ”)TJ(ËÇ׊\P**•R••5xíݹ¼N×"—W\u—ŸscV[Ù<áoœØlàux;—,âõ*5,<;’|¥I$¹$G4¡Õ{âS§#$bŸuðEÈ#$èýÚª„…{è~ãö€&€ ÕÑåÇqÞ`oÛõ‡éåXàËÑL ªÓÃýÿH—ô·7(ÅOO—J××"Þ7ÞÆ“š`GÌ'™{´«Ä2ŠžPrŠïº“\Ê6Ʊ…TçouDvóŒ©Ll›6ø'dЃgÙC8îMf8uŒÁ®[Â4íŒ95jü͵ÞŨã#z¤K_·NuÜ[}›$œîéøêL-U:b°£QÐj2H€jUñô²PŠWÚÈ°Q,-(Ä8¦D<‡²ÅœU¾…qÿ+«€>Ç°k¾`åaŒ16À3z.9IÑO;#yô#Bé —…U#$¿ô{í~­ mš#,qˆ¯m€|3dÆßÐÛuAò}î«ŸD]ç–¹¨úÍ»K(Çëê…c±sد*³ÊOyÇsÿÖ.•J1j¯Ôf^EŸ"+¾›m33ðz…Yb&ª"l½*ÖËïüùv@l7’¥‡ÉùX»ñhkãSq¼]sVŒéTBÞ»Áç8Ù”@uïÞ¯-À6Ôh]dô?&¹iu“ïÜ|Lh¬|FP‚ŽFGÛy$ÛËžL'AieþÕ6ŠGT—TÅgçœÙ•‚³J<Úo_«KÆÕÅÙ2Çj×¾”1VFuše`àã<ùwÕc£~|ÛMÃv^p,tB† ’Öj ìºåTaŤçDØW^OnÀš¾¹ðuâõ2cóÒŒÉñ÷ÛΈýD2ˇ)AÑûÅ Oq"!á0£yªP÷¶)s—j6ÓÅ.vxÒ"V n²zos³>É’[(—†S¹-Ö.6-sÊØá0ç.ò˜‰â0.ÅÌ( HH”Dy‘H–ŠM§ÍÚÚÜ.^|nkþÛ•ž´eÈ¿#,ö¶n‹|6ˆòY9t”!ŠLŠeµ¼!ŒtPvŽl…ê¼t5ü/ã«V%'D±[Æ"4¸`³Øúyl_=4žs°Ãu»úVîÝü,anÊgÍOøĬBèuþï@½Ún(Ô#{›7)ѹL üx6³,680ø[שÁ‡ö"ËÛLì|C±ëbcš?è-þë¥ +]©áZc¯~~ëàP§ÊdŠ@ˆÀú(ÿÝGW£+*tŽi?ß6s¡ß! 4Q‡:„‡öy¸í§7F$«Ý§û¦N¶cƒnA¡íª0 h›hš«;æ;àÐxõVpX#/€Ù} oåGMc*9i}È%|áÓ9—Ù¥¤K>é?ý€ÈŒŸ\tÕTE¥’$Sd’<]¶ò£˜y|"ŽIúÓ¬Dýã^›h‘n9·QáíÕçö{ê:}šÆÔD?¡#/!¿™W»×Kâ=å:ÿo_eý{&GûÈMÕD…°3µÏyû29€&Uš¸„ƒX‚HòNßGóìnÿk`úã‹¥Ýzï”$6#,®ˆwˆƒ@e\C1DDîÊ?ð$܈ÿbc}Äw33!ÏD‘o%«š$3ü\“ª"ML\îª"ˆ¤¡ô©ÞF#$ûæ®pš<©L±hŸW¨@yú£PˆŽ©ãÏi.²ïnîÊaôE»íë4âP[k¸ ô¿×k¤JÂ?)Ѻbþ¥úqÒ L#/XDÆ*^QŽøšDåç“é©3±A„„Ó|ËôÔÃ3T - YÙ éøâ“1€€Œyí·¯ÝsÊ°ýX¹Þ€\#Ku{cð÷J¢2—û~€ûâ€yAN`…L¢ºá×È÷|ñ ÕoÂÆ›‘5a3¬œµa{ |–/X: P‘ðûÕ°ò‚"õ¸E’ Wƒ¼Î@À\ø#^E¨ûÃÖ]5HõÏùésÆØ9ÍñÓ¬}/Œ­³!Ùý›òô`mSAêÍÎQö¥Ù»Aã¾?²è£é)ÿC³øfõÃ\ݲ»j8ô|üw[¶ê‡}úA÷ß¿’p¯§¡øÞßÃÔç$5µ¯AMà".Ï#$怳·§¦sìÜ¡ÈyfÃQk_‰U€x8ú/µÛ+"` õ{G_Îj•¨bP¢L…I$#,#€Ò,·Òc;ÊB•*è§üàûoõôgS³}2Õ‹Vç™ 8)²­?Þ¼/@¥ê*AÝ©Û-§ç•¿ `c, €J!ÝÈz‰:Èÿ¦]WG~€½ßÏŸî3ðó/ž‰û¸3·iå.Š©\6é ‚š™3»†£÷d²rŠ¹¡>’×µM7ý³Š )‹#É)WæïïÐ4: ,Pˆ½èÞ]òþÛ–…æå93O~6Fp“ù|8ü•µ3#$éì¹bíTƒÄ(œî#,K˜Iáì¬íAø0&½JlÖáôP^Ú²LMmŸhªc?|ñ‹ f]>.Òÿ>Š£åÑ¥¥‚KfxQÎ&'äÏþÛT‡QôAٜؔt퀱ZJÜû„YO‡iôÄžäi6,##,>]>Ü­zå´ŽPõ°@Û©9ÇX aa¡‡ühë%…¼‰z›oé4’ ÜºÙƪ¢ª©(NKoó²aè¸\á'×Æè\Žæ"õ#,òÜ3¸V?Æy%ˆHcHîM´?miŽÊR’:ù7¿½„õ{rk¬‡±÷‘¢#,qÈî•!¤dæ­>«ÖiÀý#/k៦vxýG<ÿNÿyÏ×°üßÄ“œ!dIËf´O•ÉáæDu–¿Ö=Ú¤ô4ÃFÉB ¬ý’¯óXЉÉ1NñèmÎ)¾ ƒ^«-Z ÙybA¤šìL3¾¾øÿ·|†£k†‰­*©¦t#,ĵF¥<Áª¯œ7¿)øSz]ù‡‰`uÀð›­E{|QäIå)²!u‘P™ØøFAˆºùo«ýp›fzo•ºˆÝ#/=0ú¼=ÍBûUÓVAÄìÙ3ÀÄ·±ß´vš'úxßÖýbI8÷ùlSXß½Y% q߸n©ÇA#°ëì_óúç¸o«ëýC±Ä¯aI4ˆjsð®!ÑQ¿-)¶-ÓòMé#,gABPOeú‰Èw¨þÕ¥†Úú›7ÍÌ å¤É *Ý0ƒÜþ³pç’Œsǘ7NÈFaתÍb(VÇc4LŠ/…„ï½tú|æ™é 2&ˆBžÑ…5Â6‡…ܦ2,,»¹Ç|زØR¢"ÈQˆæY…ÅÐA¥+Ž˜:Ö4Ž{Ïæ µ{ñ}ÚÕ6)­ÓJN`a!箽^Y›#/`&BI~™¹ËÏSjÊßEäßãü?Î#$Ƭ&²‡= !iÛʃyéëÉôþUÄùÿ¦…½ª.ÑÄ7^Eàx:¸ ¦z£:#$yDJ+š@ª   Æ±   °ùì&òˆk7O…)Ç€tFÖ×›B“±ØÑðÁ…Ï.‡ª^Ñ!ÅtãQ~‹fÁbƒ÷-ªÒIpJ[¦”.¹Qf–(L£Ñ_ 'bŽËƒ;ÀâOC;Õ_¦ä+œS%£T¤ ì5 ôœuI˜Uîš‹írZaå â*šÂÔhð¬De¢ç#â€ëÍt@ŠSa@¢…¤!42š¢‚„i,÷c+&œí#/ØÉh„L¢3´9³›©9’«¦ç؃UšciK,TÒšŠ¥ÛÝpýtt'çš‹áë:TPýQ£ÃîÏC3ª(ÒÖíá#,PllàèÄ;f2,âIÕ,Ñ؇F]0æÁ¡ÈÌ\åê¦å­…bPõYˆbŸ¿W8RíÊ›É*:dõ|{a,t¯[žXÝ¢)HHâ•ŽÎãòobŽžEPSJ5‘{Å Lê0Y»Eûæ4Qi| ôL¯nG[ªO8«,›}YE“Þ^×·cØqt¹³xH0«¿Ó°H™E• ›îãVú,Áµè´Wºtõ¬æ>…ÆfiX#$ÅsÞû áÓÐôÖãí^'ߧñÖÉC6S?4Æ7˜L´„€œ@Âj•¥aÓcllfH‰-LíwwZxìŒÆ"4st‹šRA@X-£µùkO6„Ö«¦óÓãÂóíæûñœ¾WÒrø¼ÖP °¦F2¡E• Ú¦*°¦0iDëøkÏ‹lÃq21ƒŽ0Äb#$ó:ÆN »rœH÷óÅeÞ¡»bIM)²˜¡ÜÝ Þ7†ÁO•F’ŠNÒOõI:,v;iï®÷v|ò í­«ë©V©vOZÃ#,¾ƒ±‡l ¢Ù \m_mònnÔ¼MQ!ùÜ.ÕioÇžh¸`áPP¦E ß8Uã&B®¨)à†ò"àdÄ`P #/×'xy¾¼á­#,#/S  ;¤,)ä|ÓñçÚ/)eˆ„C&u¦…ä‡Hc©•[}$ÚÕ9Ú¨Þ°¡k«K¤f¨;OÏ#$ìwÜ t>”¶>ûa…˜c2f¼ûójδcáV‘ŒôfÍðÐ<¼÷Ýlˆæ–6ÿÅ’¦,h!xQ¢ðÏK¾‘4&r\áfØëf)h¨niŠl™„­ãC•ÌÁZ6ÁmÔ±õ4 £cQ#,D4Ô:ÜhÆŠ4 0ú-Gñd@ñ˜#$†ŠÒ奉c‹6PºËÈ@˜‘ ë¿â"l^~wS/Ã1ÇmtrÇ-ñ[sF*OÓW¦-_q^{öÛcLŠ1bhÊ &Q4d¶ "†XTMPÄVǨê¥ '‰X£UŠ d""À§›c¥kå:{õ9mŽ pjög²È)~ÝlÀ¯ŒçàûáÏÖDÓ¡G嫶°52ðœ4›DSu#M©;´2@Ô 6ýÖùAÒ·}lïlºAD=8+_#/vIWLDz#$á®á9;'JI%]-¢à~ÍV’§éœ1N#,Ï¿…g/!­‚kT”AEH”Y-¶;Î$mŸ%Û±ƒÒ1,íûÇoØ·þ;0ðÆ鸘!áÆ°uyQZ·(b>6(µ¢=‰bÁ-žãýùzï@Ðâ”ysüúI|ѺÜò¶âµ"RDÕTÖÈT?²er¡Œ†öJFâ¹VìÆçÜû—À¼èœ‘sûý²[0J´6˜È†(Äq7“´š²"²#,t¦jb¡‘aTÒ0Y% ‹2h°†„à:ÈØ6²R(ÇH¢Ž y’*Iº†;û®…ÀMH†Ò+J†ÉvÒ#/)$Õ¤o.Ø…)ÚŠ"0Ñ¥bÈèQ„Ѹ&bÄÌ´¤±Ä:Ûƒ¯C@ìF5j#™†‰&Ć!‹L .Ì7—ëõñ{?O0ãBHÅ6OKD³Ò#,c!1š†4„LÏ·:×:VùÅ1¤w.#/WÒ<¥Ùž#—ŽÉ¶nqX‘ú»£¿ÎPâ6kŒ™_K•ÆÎEêRiüœ©DxÄrÓ‘LÃ4þDxÕ2ŒOÜõåc;›Gz ;ŒŠYu–•Ü×!­¡`·X®Ëá¼»Ö`ï>xúsé Ç p#fâ‘ ›Œz܈ñ×¢¿#ˆ#,Ê]C“·k–Þ£Ììó³ðâz™)ac·#$ÜTy’¶E”c °Xw$R@‘9¦Ïa¹C¢Ò{ŧBûãõëºL˜ì ƒO2HL³âœÙ‘vâB6l%?Óvó~ ý+êëg@÷9)ÐþJ(m#$Æ(†‘#/úg%°9®—RŠ•qTé‚‘¹¡"uQh¦4©#/Ñs£pµ¦cdä\PÀZÚæ1/üGؼ¶÷eø#$còíÛîš!æHaC?âݶåÉ•i"1E#/̈ÈA¦ü¼¥}xUoä.vaÄ!ð{eQ¸˜:¤ã'ò– ÷Ö§Cú#/7³är¾©îʼnøã߀TØéÌD$/…,¶ÌWŸ®?ÙóøÈó‘UŒOózíx8ívõìí×XøåCÐÓ­–oef…'ÕhK:–º(‚ó6 bZþJU1¶‹&të3ŠXAdX‰b±%2µÒɹ·Mh¶å¶é¶šb‘Z,ÄB0Æ2;Kd;Ø*t´;y–HM(dµ÷æ¤ëÀºfmj$ªjüÝìßMa룧óŒà“VSÛó#/‡°ö°ž9ÀûP€o£‘o¶¶Ù¸{ù‡ð‡*ñĶý¡¿7Û ²s¯º ºÏ‘òòsoG<0Ò0èRìÆJ5Óth,šŒþK¿nÁûÇߧGGZ 6¨žr–‘É=ÚYݾŽA/Â<9oÏá¼iá¹ýx:€äcú¼Âÿ>~ÙÛjÕµe…¿ÞcIê†Ü#,Au½bæGÿnaKì«$¾3ð?º¼Ñ-Çã-ðé[¶å+³)“Êàû=u3¾Á¾ïg!éÑ'Ñ.¸Ýlw{6"a*l hÒºˆ%ÁT„s*”`Af ŒtüqŒ ƒîø}_ðáØ;gC·§Ð0iùÉG…syéUäÎ)u”Û¯£Š¶ µ%mË b?gõõþ„#$Ž±CÙÿ¨0¾åjÆ5&¯ŸëýÙø€&šj¡$#/IÞG¯mЮŒ9>àTxaò'~ÍýayÉñ)ÅÈŽOâŽTÄXT(¶#=NÖ‚)›RY4Iˆ ÙRÄ¢üN3F›~òôvݨ£X5RŠh‚T IÿTKg_ÔÆuÛÇÜmׇgöCû„^›<á´Û"”¯Þ¿>)@PéÙ,'P£h€1(p‚ÏÂû.elE)’¨ ” )%*A<êî…ìMzq¯Ã—ïÐú?t¬\¢Z59<¦¥ DCçÓñþ¾§ÃOº²Ž‰˜†‘dF@tDj)"sœ¿Ê–~tš%‘‚ï“’ôþú ¨Ú#/Þ¥\Cmé$mo’ÔXŠ!våQUL„Pñ„OÑ‚1ö`|eæ³ÊŽÄë*Ω”Æ `FÅ (i_ºñôKHÕ+ýŠàà»Â¸2/ñdµä–ôµ`úc,¿¼ýÔþf¬X¾Xãüí.ƒ¦.!JÔ›Í]KÛ¿ûgáãpú% þHý/ß³‰»öñúaepz8xó.'#$ùEê¡B‘C«¡h#/Ví->Ÿºõ«½#,#,”ó¤=”Ý$‡ƒ]VÛGq˜_®æKQ#/ƒÑãžÿ¶¹<_š>(¶T(`£ ò\šoXdQP‰¨—Õ¯8dÆ]@ôKþ`Êß‹Â|â2~oSczKÒBm·êŠ}²ÐM&s*ðJOë¦h!0ÁVê(Ÿ)#$Ã7éý»¸h ýV)9t ù‘¾hqö{ÿ;_Ýèú~'é·òý­û^!îïú¾¯¬WÛÔ¾nI•=‡žÐå´õhçc+`ûæ?ÊïMKÿÛª[;:n6¥ÈX×oÓóŠi·»ïn »Î·,®wøkòÇ|~fÙHÚïÝ v#,5·“…t°äíýÐHÝ^1jIÂU@ã¦4õ};.H-Q;`ÇuçÛz—ÈÍâ‹J_Û‰V–B5¿ƒ€6´€àw_“@ó/‰ „E1ã«ó¦2™vïïøÛ‰ó™w>š?á×}Ê ‡Eú=.Ê6q“ïÇ>iw×…!Uð`á1˜·"Ót©o"Gæ#øQbr#óŽÁâ>Ò)ûÌ÷æ3êXá þ54(ÿ®˜4ô}”ùÿþ?´Ñ÷ž&¥Rå<ŸÏŸ‘À³¿9#,†5Šl¾ÌoÙß߀5'k,HZS)†·BãES°‰9ü;…Ïé륾'ЀÛü÷Óyfœn:aäΔŒ&SÉTØT”z¨šçešª™«0m$(pRqSÔÙi_ǵD„þ{*õò#,yÔ! 4òWáÊò ,ÈW•”'aOë£ïa¦ß¡¿Dű\NÔ¿zE7¾˜4¼P~õOׄ4™MÜóÕþÿó³í ñ°ïõÚy_¾¼'¾ªyÑÆÔ’b°žý~iˆÓ4јŠÂCcëʼ¿±BïUWÀ%Ç3ÕæØÏ)ŠŽcæ< ëRÀ`Gÿ_×C¿;_ŠÊÜý²¶ý¾Î ¼œ0½gçš™‚7CÏñìUÊR(Sàt” C 7P¤ HÑQUG°”N|Oo“ïÇÓ¯ol~ê3²4mŸ½JÝÉPq®0²X‰P´Bˆ5,¤ÞˆsR\!ñHG"¾y}ÆydZ¯˜‘½×(š›!õzÌé˜Í]]žÞúÿ§WÃÉõñ§¯êúœ}fÍÜýpUAïõt{ŽŸ]2Ô›>²Ë+Ç ¾¾ÆÎ~›X+×n‘§Ñ1¤¥µÑ~w.Zìíw±‘eïò/“Öfý·YWçfŽß»»Xݳä—-ÖZò½ñ¿"¢ZªöþÞü9»¥ÃÌ|{—£Œ›á|(ã­Á‰¿f~C±Û¢¾•iMýäZ:Ý«õnñáî×ÝêÑŸœÚ/ôeÍžŸòéø8îÓeÁEÂÀ2wgŽ§×ªzyü-˜ñŸE˜à<ÃN„—ëOgõ—É~Dr ¹$ƒä·ð~^ÝêèÇš’žÓeüÃêzoÇåûÞ9)²BZd9Ç£¥“çºÙCuÜëe;7Å´ãÖö½öcs'U'Ÿ‹æÙ,£mƒë€ËW¸;«Ù«ó›]ç$å‡?õ±Œ5Uµý¤zŸNm›tÆë_Aª;žÿ&ËÂÚx#«wF´.ÙwKWªZ|äè‘chæýZ=íˆ7ßm¶k¥×uÈÛ‚·™ê)HkïÎÊÌKͧ‹¦6i¢5#$íۤѯO‘x˜ä?b.–TÌýï1¯îþTç§ÙÆxòÕ'qôóqÇm¾^Øy·ðñ;µ“t±ÞïAözøJíW_ÝIïäØîÙ¡¡åPàˆ²VNî=+#,üiiÑë²]:š¥$Hqðê“ÓÉ%b$h_BÃOüaŽîÿ‡»[â9•šú)Öþîý>Q‹³ŽµwàñÃë °eãéê^ÿÀÏäôúG¹Ù0æÄg²úN#¼Ã‰Ü)¬gdFûcoºQUõW~6WíÑæÕ}:_äÔ-«a%ojú%¥}Wìdúã¤0?w wiGâºoú…æ_qµ@eh¡èƘø}rpÅunÆø÷C„彽äG*}ÞißèÛnQËø¨‘JüõN|Wìú[O ñ‹›Y»ôv'Ÿúü!,¾K?-:¶8B§ŸàÝKºßMݘv45ü€I/ûŒ½ò|†«àËÕÌ8ü½¿~p úh? Ñ^8•Ä(ëÃÍñ¯çÀt°Ù¦Kî[Gѯƒ¾‡ÏaÏÐæÎ7L˜J­,•ù]ó3¾\$Ø'8*,>–¯šUÿÁ¡¿ðÏB8a¡‘S™@#Ã0<ŽæÛê³ßíþu³³ì´síÏøŸÞ~Ÿ¨ýÇýnÓÝ£enæ‚d)ØÿòÏÙê¯u¶ÿB£Ó®¯÷„T…|_N£Â^vÉ¥Ûçoõg•ðÿ‘û¿¾,?pÊ%{ŒP‹5GŸö|¬¼Ãò:^Ëù»¤R[739 Ôiˆ_7™ d?/œ@ üÖ(´#$¥‹LRÓuèw3ÿ_Ù«AÑ÷zÂáÍO‘‡Ç_éø[Í-Óò}>ÎÌû„¿`±™µ÷õŽÛ±ñž§ê;¿Q—ðp"TŸN­ZV¿ÍªþA© ¯B'/Ô½È;Š#,=v8#Éßòϯ«÷ë¸aùû}ÃÞ>ñÄuFþo(ü‚…ËpêmŸ¢g¾çZ³öéÝDAþkõSøf“”zÏbgÐ>íåù~ì)ÕnŸ²¹¸iúøµnýÞËþ‹Á`ÛêN7GÛ›†Ùª=«péÕçù×Ó÷qÒŸ8ýÚ…›ù¼|´ˆ(ü5|z9nâÀ~ßÐ}©jw'›ˆåÍ#$ŽUh…Y_+ØÀSùHlgíàÓ÷!P„ÿDDñzíÄ&Ôi¢P$7ÿBqæaž4íþ=ý]ëÄ]·Ÿ§ùÈóîÐX¯ên.Ä=ü—G3¿|÷ÖdÉ~Ãå´óM}€7ôþ8YBAÜ<ÞHSàª1Ó‡„Å÷}»ß}8õó$u?|F¶ =ò¢žÝ÷›`2ßkDøÜ›êiû,³/¾¦»N±Úl–’é;ROÇ`È9ûÖïói‹àpY#,‘+!9%vJÆuÐSÑ4¯F<4θÞ=îåò\^ìóÂ7sñuÈT6Õ*DG[Kë¶8=H_ÃŒÒØQ2åG]ËÁØpöLÎ’À‡PA/#鄵µ6þ\4íóÏOÓì Àgsý›ÿX¿ßݦ@ì&ƒ½Ý, q±ÒÛƒï#," ËÁË0k¾T­(ŠáÎx™8Ï£¹ö#/Ó¢|c)¶øD¾Öæ6ï{çæµ—–Î"‰ÊçFîå®VSaclb^b„V¦?º{^nñß]_z‹èý:ÍI—BxóÉÌû#/z¢æd;iÊ·­uƒj¢B·Y7KAìHH!$ì²Ï”+©fàIü=³Ü’³L5GF Êõ?ó#,üúÇg¾ÑaǤQ=º<Û¥lŠínë)WÌÕ/ç#/Ÿ]a'JN<äs½N±EG˜t$ßôO±×ÈaŠ(ëÓ¤#/ߪÍ<ú;m•õÕ_ìì;q¹Ëõýí*G.×pÝQ«~©Ð´O>dÉ™ýåï–öl7·ÅÎÓò}\CÉdÃÉèBõ>I'òñÖÚØyÏ'yÿ–ÕÐãG•ý¼½Lÿ£§4Ûw+ý7x¬µ;RIÛµô¿>«úŸ;¤÷F/ulu³|¯ Ë£õº¶zñÂNòÿ7êöÐhö Ãx#$£˜#,8MzâÂ*I+ÏËiý{¦*?¿÷²U)ϘÈ/«…ø‡TAì’žQóü}ceëd#$?—4v^Ó 㬠U¼º3Ÿúþ”QG¥—õ,ûÜ?ÎZŒÌ¹‘µ[r²Á¨9G…?7F5¨0Ò¨6Ø©A ©EJ$ݱ!¡Ìn,$U¥–‚Éd.›?Í¥ÜY #/Í]ܦ¬Ë3"{pcÕ¤v)lv5‚Ec#,2J`B#,YCCt!I± ÕŠØ"²¸äca=Øj›0XÛIFɪ“O³ºaFf#$äfUI1KBz±Z8dÚu‰ü¿eî·£¾D&s˜Î‚PP}?·¤~+ÖS<%º¬ ñf¿ÒZ¨9+¨¶õêr© Ãc ‘F6“,# D‹¬¿êøoý÷¹ü?ª~«Fœ#¯#±E4D dˆ‘ÑÒ¬ÅÛBÒoPc Ø°©J¢L†­Abm6Ì-$•H ÿŠªP´Y¶ÏÞt~} ”ãoÇ/§ÍË2)ÏðMö ýøvˤß{#‡N4¾ œ-gÖl³L±€œçj·]uåËuž•ãŸÏ]tåî®­_»ÃÙ°KÎ=*¶~ŸÑéÎã¬cûº:9µïüãÉÞ'Švþ_Î÷ÛŸV³)åã î±lwÛ~ŸIŒ\ʶUd×vVÿ¦{#˜ßÃ\3 hî¨p°£ §Ü‚ˆô‰$:ùË®¨ügÉû?%ûu{´êöw”KP‚¿páÅÀ#,@&ª¦ß—ƒ€¶Ó«ÙÎ)ß 8oèëÎ8/ "N¿ßWƒ‘ÅÎs=Êé9¬ - <ý6¿—õëÂaSZ–êwËû›äüz5ùö;uñÕwiø"nÊÏÝ?ÇO|ŲY0¿º/´-þ!ˆëô«ŠGèéÁç­ëŠv‡ù<ùÛš3kÀÅnB‘mZ$VÒ†AÉXÅ)×%<¬Ñ#, cT8(–˜‚ÝÝ2[šI‚DdE•+k†”aRCt³ªTôäQj#,±´@ŒR±BÀdQØZáa++)YlÿFŒ#ƒÆUZ¹ÍÚŒ‚–©Z¢Ê…¢Ø„`£$éÒMæîx3#/F5Û”MÈ ©‚”`ÈB#,ÌF–Ì&ÄáÚë9µtÙ) lcQ#,£–dL0ã0¬éTZCâÓ¸èè²–×3‚HZ7Ï„KkA#$ekü.³«X#,<éD³‰:7³YhlbbÉeC…N"G«…Dt„Òdý­¢Ö–#/¹‘Tä"Pgj*ˆÂ®´ÊŒp#®²R1Œlž€b¹Ñø%W<¸ø!U†$‚’IsJCÙõC‹I4&é½’ôAŒô»/¾¨Ê^³¸a/øÜβ߼ÈÔŠ#/Åíç#/[hä ±S'›ûÔ? t"°ù_ôZ®Â¿xöéèÕ#/ýå¿aÙ­¨õ)ÿozð™Ó£Ë}ÓüÚŸ®»»š)ž3»0óXõ…ï¹~røütB&Ȉ‰Ó£Ì½s×N-ìË]†~[~=.Âk,µ9ÄÞÏÇò}No#ü*Ôõ@W±Ê ½s’ ‘•ü#/wA#$_ ð†${‡Û¯šjGCv›*8¦ÄWßé.eÒ ª’IfUUk{T~h$whM 9,HÙbzxwˆ øG?W÷Î\Ÿ@t¿/Šó‡àÑì7¾ÇðT‰n«urñÚˆšÉ$P(?ª‹u<â!ÜC½¹ð/õO¯æå|}o¶ê )Ù²gF=¥YÈ€*@*ŠA“ ™)‡}C’"³%÷TÅWsžI6‰ ~áZôëÑóqã ,^¹vçÌ"6 õuJ߇ÂÑ*¥ØP¬þMeTWùªÛF+,¥!FäEˆj%ý,VÀ'ûtÞm¢^[ÊŠŠB‚YQYCFF¶Ïl¿¯ÑÃÍgËÖ:ÿ#H-uí;wû~ßæÓòÉ ùÖÖ]¡€ªEˆÁÏf¹°ôL‘Ìs(²ýh­¾óA1³†#CÐá#ipkvé½¢šÁp3¦ª ð̱„A'š•šcÕ®ú¨« Á­A‘Š¼‘ƒX<Á™†ZEF L¢µWÐô=Z^%ëÀˆÄ×Õ&D=ÓxŒÇ‘À­«G:ó¬Ã”‚X,ãmµ‰îš  èrhŒ5`£yTîeLzDm,ݹÁ²#/¬ÙWÀ2ä²ÄÍZ¨¬ÛÕ§XCZ­¸ÆÛ…‘2SS¦¢f†¤ÅB(„6ZB„Rd˜– -£w-¬™9¤N½XkYX6ÝÕРÈv¦êÀ\†Ql›iB¨ãÕ?‡ù´hÐwG|ÃZËÍ*¬VkR¥B§‹†@ncJ{d­¿ ¢¡8Fñ™ßž #dƒ§“|üyû¹?›öuêP‚ ‹zîÝÍÌø¸Cwp˧Ê>øÅÍ5‘£Í!âA˜hcŘÓd/‹öÙò2›˜pÃñ#/ Ô#/ò÷?ü:9¦ƒ¤¸~Žäq¹Bߎt¢zxîG¿CPxû>£ðÏ#,<Ú½Wô§H'¤Ð@ípZ3=@>“XñäDe–AbŒX°´ª©øÒªˆ4ãñ»ÃìYˆˆÔŽ‘qq…áÃJ1¤J>©ôi`ªÉ.HŽ)FD‰©„8ÌøXÕoI¤TëšÃãÒ4IéÝæw±‹jÃÓ×G¤Ózt(qPGcÈE{ž/F°4¤´RéhƒD%„j64(¶ÝÌFç6®•U¢œBn3éýŸ®ŽØÌD:çTÒ‘I·c…Ñù‚D†CñÕ¿ýø¼þÞ»öû|GOïæåáéÇ|ÝzEÙjò “éÄ~?ÏþŸÓÏo¿µEÆóJ|˜Aº|fϺM‹–• ÈÜ[ª1ÑÚ@ûŒô¼f›Ò ÏŠŽ{µÌX¥×WÅî½æéË“i†9БZa Aæ ´Ž¶ãouQ”¡]VAü²–R7x26ˆ¶<ª¢‘¨6Óˆ®Ç!#/^Í BÑL8PÉÓV®g‹&CÅ”93Ä»‹GÁŒ¢Ë#/‚²kÉL¨3H/˜! #$PõDŒ¥J)¦ (ºs.`v[È¿c!‹›%Mƒ\ÑG™#,êPèó|¶Òðàšˆ;Y$ÈÝ•CFP›° LÉ4' ˜dDMXés‹ðTuZ¨WâÀÉš2ÒŒGËZŒÔŒdmw:™C”È·¸ŽØ¬#,B”#ȤË$cÊd%Rj×~ÐÏg~–‘nÔùzebB‡ˆŒtÎ"Ç2úå© ^&AÕÓ‹$'wÖöÄ¡/àî¶4Û}Myi÷4e1ls³§n,-ø.$’C,ruÆ6•žš#Ô‹Þî#,Kqªë¾h´„.ŽÎÜ…Ï9½"$ïnîÐCj qŒz±µZ$Â-àLd"mZ®GÜÏp.›gÊh#i™£^ÞxÑ{æ5ÓlfÁØÑHÞKš³“£ ˆÒƒÒ9Öi6!bÅ>UAß5W¶¬ÍíÃ[mþ&Ò}ÆœÄسV‚ƒb©Ç´Å›‡/ºîˆËîm±š¨2áBaµÇI¶v7…¶¹:^V1´iÃf†gd"3]ä(ØHeØØ0V âþ$D¬?•†Üq·œ¸ØC²IçgÚˆêŒVù³¶ã8m˜bÜöpó€¢Ó„Ð0­#,ï)ÖçÜŽ›4ÊêìoÄé…m!& &HHc½·–,¡|úçkÎíëÖï«È\´¦¿-wj]CKpùGYŒúf’Iiš’HÐ\;3¥cØñÃwå]‚'u´Ç ƒˆàÉoÉmˆˆ0C¹¨än*6”¢Þ-ó‹dÛ¶µÒ¹Q„’ƒ[#,Á¢<ž#/:26#,Š^W\m;ÐëÈQ¶ÔuvwD“y‰d­Ü*78Ø(æòÙÝ6øìŠ]qq¬ûè5‹#,À€Ûk[írã£åÒ+V;B'F)ºêèã9““;6TÊZ¹f±0Ljš¥Ó¦ÌNq˜²pÆȬ2Ìœ˜Ö…M‡#7ÕÉ';d%„¹¹­ÖîاPÆ#,Ž]¶ØÉËH'’mjM0ˆ0Úy›Æ_g¸åcbkË ÕoÓ:Ù¦å­ úŸ¡‡K4]µHè·Þzýþ˜ËÞ±I”I×*J¼C”îK$x˜í;¿M¥µ9`Ùkz: ÈÃÝ rqB1’ª7מm[^úJÿ׸ȓ‰ÈŒlI'V>Y?S#/kn¸ëšžÊæäýx¹­ö]x¸Ù¨[¼Ë&'&ÿÉuÂòu…œ¹RM|an‰¸ê!Ô¥•“ÄAl©·K¾;Æ–°´‘¼)ÁF§P6ø¤,½¬-®eß4ð¡“:R(½³#,TVÊDèú„Á ’`Mß›¢‹?ÜémÓ£ºJ÷Ï¥I¦hi¦ÁoµîXcOËÍtžòÂXä†ýk‡¾Üw‹ëš ~a²ÒÅ7iœa\±}:®³®«KiØ!>̇¡rÎÜâ°ñ©lš¿ëq÷”D>®g<¼™¬FAѤØM,ãsÚ ¢AÓ5ÏIYº·åÀºåG8A¬ê1‹&…røÃïn•$›ÑM†]†pÕÙ4ίEy ÕÒͲó1êi„º+‘›~øK¥¸[Ýûs–†—E>iP܈x]#/aF.™LÍÐiÓÏ@òθ-¶ŽŠ²2ï%½&¤„š`;]SBtÑÅÔb0TX«ïuwöW›nï!7û_c|¥õaǘ{³= θÅ"^yyXàV´ÙM¶µ†«`”Æ3ëÊ„ÿ댘£¨ûõNæ¦tgn0†QÁ°0¢¨$‹ÞìÛô-FñàtùTŽ?צ²v=ã)ûÍ.Ö”3¶ë™E3H¨œdQ*Ç žäÄ·ÔgÕWêÇõýç鉆®µ“ƒÔž_ïÌ/ÄÓÜ&‘!EU<â‚ÌF)¤A]…ºÿbZã€x}ÆWR6¨X¯F8x“ž^Høé«SÅ'Óäs·¨àOOèÂ0>_]ê(ˆ³Ú·ÇÛÞZW(Ý‹Ž¯3讕ɰ>cáµÙ¯#$σ-Þx úŸç1­$¼I2ÄÞ‡˜&†µwTR.‚ö¨°ʃ„—È0›FB뙌01Ú2ϧÕñü¬Kž2ïÇø/€¦Xù” £,Ëdå ƒÌ’À8O-0ÂþüN¯ïײÌûÎA‘߇ðÞáA`£`#$,;¤#ÂÕ!z[x0¥°nÚƂʸËRV¡Ëi@Áœ9»`ÐÆÀ%•Ã¦¹Hˆ·+;ˆ’ º úײ#qIö@OoØ9Úyos&ñBqÊ^L}æµTþ£ÀusùÅÛ/K§Ú?L,‘r²m8=õInm˜§OlÈR•P÷ŸŽ³þ×êþ‰lg[%^õßþîóÎpÎßI;ƒ³?“ºX‘é©Þö!2f*Ÿ)×Ù”?#,ã<#,‘JJ·d²àŒ¹r £i‚U‡ð%·6¶L[2;BÑZ–#/9b]­8ð3ŠÏcÝÇÊûK>»º…&Iˆ—ƒ,\ÀÈ›|jÌÅg}'ðHÕ[*Ãcº¨wj¾’R©!S&ÊË'D¬G¬\'›caOnµätÜ8,^À9ï’dþ¢®§—VÛy2»¯¸“ÌXnèí¿m¦tGIáRÄN4e‘·“‹fôÿ6õ¨nÅšðú(>BêÞšNíÑœú©(rÜtq•ä¢¯¬/v2‰¸A”"H9Ä•á2I©½0¬».:"‰7È÷ô}Ó¼šö¦N tß>Hhp2vB‡TáæÂúÔ)@Åԙɣ>³âºó:Ýü¬Ý© n’9/FÞ¤nÅ‹ýBÚ|£¬ã»L_AäPÓSO.Ã5)ϲ¢¹l„¯Vº-˜—^¯ŒùÔ:Û½vÐ$N™ü;1(ê2Ó#, Çhr¶‡iÅA1ÎF™ý•Î3[ËüÈ|¿ŸL™ñcšÈ+YQ_#`#,9àùYP³õ‘ÄElͽ¼<Í°|øŽËC£˜“–Â;‚Y†âºžè üÊmôöjìºè‡´óµ´Iòó,¡ã­-ñÕõ×E+#/S«NÔ§Ä~P;¤ñ]çVKè³óP;ñÃÉ!Vº¾huZ·†I¾ÚËÞÇ[oŠgFç“iÊÚŸ³YÌÔîå×#/Ô䎋¦_+ŽƒéktCú¸Õ.Øy3Œ‹eÆÊ:/âçY©ü‹é]#,t¦ÂÅXɈp)>”^Ÿ¤–fļޅ3ºt½}v²OŸow=D0 €ȃ՚5¦]彑ÝÇŽÝÈj߶)yoÏ…µÝ nDt2un6c+j/› ›M”Õ}“¬é9ã¯û„¨÷’´×>yÓå[œ¶”Poªµ¯Q¥"4¬#,Ó{K7aêhJÜ«„,Ûh\-!…õ¹4܉#/Æ;®Œ/繟ͦê ÓsT»f«ùW#/­/á9=jÑ´S½e˜‹EØàö¹ÑæÌB#$ÈX͵º9­hªâ¢ch(±üïGGc×~N…2ˆ§’ ‹¦\Ølz†Q‹ÿ·ÏjJÍ¡²Ž >zÛ ö‰ÍÎʶä©ÛÂû]Þ`y?%ad׸ª¾í7X¦ÿ]~p6œ áLqi1Þdì2r¸Øû&ùÂØyGEVf©câ’»ž8ŽV8úý5לÿfíæQ¹îVKeœøq¶£ ¥‘{ßuˆì{ÃœfÕ„WšR¹nŽÇÖúÜù%èmvá³ËW`§nã”e’B{ =ûŽä†BKʽËsãÓ.\°LÔr…ùN ^ã`°h­±1¶¡‹Kƒ&È:r5¶bÛà¥héZúò=#/£g#/¶‡ôÜòëÖùýÚÕæëÖ©å%2£²Õ<ªE#ž$­0ü[„ús¿]9Û^¤D;8bùY ¦÷h€ЄBáµl¿;%X]+#v¾šýI1¯•´±+n†Ÿ^¼iÄ‹¢ÍM<Öõ^©u\]ÚñÆû­Ž«A4ªI…¬]×ØÀ«…”x‹®ÎÁ%Ö¶/“Ä ­YÝ/§&¸ãY†;õñ;r™ç¯¯Ã¹“u™ã²š^ouéÉØŸ.úŒžìqfyÓ`ý£kŸsò!“ÁG«Â÷!Áuè«kÏQmSRÏ…[¡Ðy@ýP–¥ÙIËȔݶ.Œr™/zØCŠ“ÔNmÝ•/£I—od'÷¬/aC+fP·RìÆÀÔ"x’¥ÐQ±õ×®)t–hUÔƒÊw¨ {öþG×J:g=#,Û%†×xÛ®&idòyäõ‡ºóaµÐ«q*húX燫gäÆ7Ý)‰Ô5Ä­ÎsÂónˆ%¢”ž2v]‡Þ6ÆÐÛþÛ+™Þ#/–~G¼2)¦…•–LÈgzÿi‹¨%C#$Ž»“l¢/òJ×h7›»˜i;œ†zÄ›y6͹å8‡(Û#/>,˜ißïq®'Øö÷MïÆ~´^³ŸÃ'·Þ`â©“O§8Þæìx2,­Ší¤® ÕAUÕ`37”Ñ0¤`ósì¹ï6¸VÜ粎•«,üóqt²¥ö«¯s¢öXKAedíµò9)™ZjÑXlÖÝ‘„ÿ(ƒ[XnÜŸ÷®g¯ßõÓÂ\ñ˜6x6¸©@N8M0Õª"¢“I,vdc¯Z%U^7–ùÑ’ÜN¸¸L“#*åK%+Y9‡“},}ö ¥ax«aãzß6D7Æm-üT‹PH†‚ÙÏL„’ÚUñ¥Cå··+]´ij=¬•n×uÚµs¦XAÒHë›ç-« ß«óËß÷ÿp½ÖQn·sœêY̱±ê ÆÕ N–dGNóêâÔrÂ:”áNÕ1ž}ž)ÇWÙǾ±©38z†%~×rýw–›ÙÄ¢3×™™L?ßÁÊâ¼ð/õàÔ,èH†Éà]lZËãKÝMeÁÏ”lŸ”Dˆ²»ÌÝ4S\gÍ?®ÝgÞïË™Ðeûäð»SÖ³Û{›¦óR:b˜máÒ!4¡}oV}u†Êõ¢ÃMíð{UÇ”j¥úAiz‰¥*·‡uÑE‡¡o#/lçÃø’ÿ7¯©ë©8¾N$×õ²\4_“›ºB–ÆQSb²KƒÅðT—‹¬sã²þ˜5ðË™æ(H\‰7°Q¥1Q¢¢ÑWÎÃÞ§ws•}2os Êßu<°1×ô\ o¶1‚¡2õq¿f©3¶u-IDlÛ7Ñ ršA“I°’ÄSC™Áh\÷ÎXKSRªa%‡.á±ë&<'k’è+Ç0­¸¼?OcVq1þäçÏèýCÍ¥¯tXÊB"IC°g¯øwj¾r˜BWzâÎm^ljÓ8D”#­êÝÖêb-êóË>“ZL©_ƒœ“=ÌcÙ –”/P(P9ß]ÇÊ 2$È@ÑèhÚžÁ9"1ÎÌó„L)èè~’ò @+bª^í@^2].\}ý¯–±%c£S\iÓ%Áíqw]ZËùÁìî]‰Y!#/U qCð“tkQ,7J÷–¤„ÃÆ ­5gô>¤6(„(ÜtæâvBñ'Í잌»¹×LrðÐì:oùyð¶·lMå“\M²÷_ÈøB×MÊŠ%,ÆòJ8åèËt‘£NX#/S£zº3fY…Rïš4«¯÷V‘¬|oé‹õËýÙyÄ ]£x•fM9×%”—\U×{šGÑCƒ±œ-9ÔD:ú¶"Ü-«ðpbC˜-,psŸ‘Ôx¾0’Ël§Ðí5œ”‘¨êÕfKeŽ¨Ûwò^bn6}³3ˆÍSnQ¼ÁÄm w[Æcª<ʘÝt:kgå¶Ç9m.¾OÆw7™íÚŽh*ÂfEÄKýQ=h.w6•tÍý›¾šoôà~1ˆßÊÜ4=ä6êI‚Ä8·ñÃ}'¢sÛnn†1–‡ÌLÅgã*t|cÝW#/fÞ%-ê9“Ú+ùyÒ;;ô‹•Ÿ4Õøê ^JºMg¼Ý»\=¡¾ËßÎ[×ã’/ËÕ¸FµÒqå5ÌÓZ:ad*”u™ãÚÛ¿Eôƒ•<3‘ëŽ6$¶åñ¼¦tcQ\\?ò”Ÿ¾*QU„º–é#bR-I¶MŒVѶ®¸3õæ N$KDBˆ^täÍÅ‹ÆÇŒyLÂúfõíɯ·„ŸÊ‡Gcï8vœÉ:ª¤Y#"„X(1F²ÐMS¯2õ]:›–r:L'Lž¿?‘ˆñNÕ|[9vZ?jy³2»0Gnùò‡È.F!QáQxï][Ç3kÑÁuÛ_ˆ7pFròOïaoãèdý?Xö:)걸±ÕR&Ä—wJSbíiK88¯#$ï?’œoú70þ-“ì?›~Ûvˆ—çe,ÐÐ-=å–$>xÉÄ‘?WèTÐþµÅ¦œUM ¾,†OLÙ#,rt,ý¢Œ;A)ý[ÙÄîKN¥¢½@ *«2Þ(ƒF°ëõý‹÷i÷þ$«™à¸•hAºlK×:²ts²„½~×eœ}›¢ã(í ù¿c;šÑP9=F£&È^ã.Ž`ꈇ–2P³7hÙÿC¼®Õ%×á9æ¶ÞÃ<¸4%­¾ýÉØ€j£#/#/dY#,~ÊœÐ膨­ûSðB{)LW@@ÛõUµ@¨t2¥åj '«U(×ј”­gæ¨ñdS,ñÒ°éš“Å”¹u$À†É„AÉ5 â‘'1(´,Δv‘½´K².¿òˆc#$×úyjîØbìs±a?|¡×Þ?ìÍÓ}c••n~”V:–íB{Ú AÕ&Þ~Jôwˆ†=¦šîaGZ$p4°‰¦¸—±#ßcK–½ðÒš•ðíã“š‰=œ(“Wnê:£¦¦V,VUv#,íTY@‚òJ, ´“ y)¤ã\†èT¾¦Û¿oL|ï÷È,è¼¾7,::¡·çî¥G‚“ðÖèÞOýÓ[?’Dp; F„-¤ð¾ôù§P΀±|6%2(/ÜIñôùc잸íZŠ§ª¤ˆw‡ùËy‘áyü#o2P„!D7‰ØC›ôÿ=в…ß®¦™­®™Õ¬>µI=eJP(Z•U5/ØÜîwŒÛˆ£rj)æÞôüôk/wBò#$ùª¦`1…$ sÛ½õX“ãÒê´ÉÇ1¶ÿI”5™Ä=Ãi¤S1­kRÞáA*u&lÂ]Ó­QuŒdv 4›b@Ê8ÂE.©¸Š;bœrËõùŸ¼Ù÷à º×˜ñ:`(#/ „;{#$.uš…;!]tnÈ¿V­Úöìª6hô›j"Äßó(exÂL LùqáÅñøc‰¢ ù¾n¦åDD­…låÒïÈ#/€„PI¸pë·éwLÜmîÄëšÎ{~"(v3¿ñ¨e›!ÑìýªÔ2¾´@¨T:õi’kŒ†~ ‘oÃL²£ïŸ.N7–%LçO~/÷MÉþv‡f‘0ÔRdãmÚø|7¬yOGÇ3}¨î&t|Lú\Õœš²AES­PÁIÉ4J^m£˜)@ã3õãßP®"ûöÝÓŠWW@U=E…¸ÂϧÙ4Ðì…¥Ñ^ûŸ[¯?«^]TšÕ†q‚cå×Óyë³Gwéã×A˜Áàyå*q'#/žÎê—ÙAå#?ö³¬&ô—ÕñLÝ’ HM»#\Ëâ¦BÕ{Xñ~~qj0$áϤ<%8M¹+U¼çŽ§Z@YC¤rŅц¢`’†eR 1)sMãS—Þòg¤Gw“Ï,Ý-¤øFô~><@ynrC(kîÚáyŸ!¤c7¤ƒ³Íò ÎÈÛÈ)Ò5c1bOÓsîWCjóÍ)€àËÔ –¹#$b‰ @¶Á0›½ ~EW.ǬÞoŠMÿã¡$ˆD£ÍŠMÈ·»m¡ó<!98>ÕLfžÐi#w¤‚¤‚Þ<ÝçBË“öýÑ´õÃLtÒï·K-˜V q9EwS4džÿ §=Ý'Pý iÃë‘s-îã8ñÓã%`ì”ôßKâ®6-ÍÃ|ǹº†#çÀÜ “ËéË@ýŽO’ì픞²‰QæÑ{ƒƒôsÞåÛ#,qÛ…CÄß°·¨ŠOó.6¿¼y楘qB[ì_§¦Ô|Ngõ£~Mqâož‹þN\æL퀑`wdÃ@à±0#/.p…¢Peäiv ÷á;õÏI¡ã afÑšÜ×£ôj岂†U/.G“(>žåçG¾ÎÈnØ=/ôMD\[[m~ŠÜf'À’¢$7ÒÙ¢½ÉŸ6nX }<Р scɆúØ–¨EH5Ì ±ñóíœä’ öœöEŸ*ä¶ï¿”~4–ÒÜéÑ•‹Ç?.e:1}Ù…È’Zák®1ç°‡À螟7¾Ê‡ö»N/†|d²ÄÜRRZ"B_ЊòrÂñO&ÐþÊW«˜î?Xs\wâðvÑ”¹û1#WgHA^ëƒ(¤Ì¥Ý~›™Um싇  `(ÈPÏuëˆ!Ä<Ü‘v—_ÖõÛXÃVÎuÉùÜ¥V5*Ä^ErÛ›|¯Ü¢Hi7ž·Üu'g ¬f¡{7§¤ ‘çµ~G#$í¾XŸ'á’™…DÒ– VB’~**äOxàÀëáq"—¨y¯`QqNN‹Hw*´·ŽîÁ”`é&ÂyV £;sÂ!!QêU{g¼‡®–e“lJèå[¦¶=o—açm{ïÚEÍlä»ïÛÔ” ƒbÄ“ÅXoòR„¬^vßp„O_w®£)ê囜;¦ES—Ÿ9Àzƒ°é¶1•hó§úLªòì÷â÷ídø~®wo°ØÂ(ÞÂZg¬zÖöÅÖÑøKÞn.íï]ï\F.PwJ‚íðØB”pc={qq%~~DÙbëyÄ8àHª2 Qw=æ¼8EÖv¤…³A›ÊÇ,½RôvD¦s=|Og‚ú«“dFê$Ç­> 0›Ý$ݾT“æÚdéP[êçÃE¾fÿƒ4«`ÎpqC¬ÞËiÛL-Ò™#$S®v ðFT(‘TxˆöM4Þ­”b„ݶ/¯øh€¶´þŒ“¤‡‰ñ!2;Წóot •¸o)Wц!åiOò¾ —ÔŸ#N‡*_Ö™Á4úÝLˆ‚ ²r €±Â&xX¢Üó,u=¦ßuœ»xAår£c_ÏAg³ò<²úlÌ#IÁÇh÷ñ•bìãšc°«Ë"A¶6{JJÅMšQi"4Ø›NÚüøŠùgLa7^#,rgqžÜŽØ¿Iºjcq@1A‚‹n@c"4ìì¿öQ+P+:m 2hTBºÈµÈ†ëh}/СñLJc>†úÈW>¶†„cº^H¡M%TËÕ¡ö*Ð’žÔ?ÙP))³.„#žç¤A¾ zŒ¼x¹Z:ΠťTªŸZ5*Ý…Æ(”„¥V÷Wû~÷À;jšg’P¿ÙàòË®/ÛUè‚íòQd#+Èø²OÏçßXå —}U=Ù€'úâúdüÃßØ{´z÷§×Û !þ´žªŸúàEŠŠÉ/üP7@´Œ?Œˆ¸?É@Ž pý_©7ܾ¡$÷øúã€O©•/šRß ðSÇB AWÀ€å´¤z@¯£¯g„×*¹ËÆ—\ॣ)•Ib“#/òÚÏ!x/²Œ^ ¤go*äCL.›égß¿ÒæÇSÃ7!ÕêÕb|kÒDMðÃöþ-˜öÕM¡Ò0ö{¼s¸ç¸ÖËëëaÊèœE@RBöB£àUéSD;N=ÝêŠm˜ŒulÕJÃ"0³o"c'Ö÷øèÛs~Ë#,ê •@Ž´AÇ€ôô–Èß ôE.ðîµî7 Ô¹êÃN#,%¥#/ºñ²bcÚ@°#$£òä$9nP¥Ò€æÈòûü?læ*h œ­Î²¡Å“ʼnôýöN¼èš¾íFìË$Ú ~ðä@w½7vøªìü짧=oó€°æ#/„(kÀzY#$=Ç÷Ä,·püþ70$Í\ÅÿÍÂ6î÷Cp¾ä!¾%ü°²ã”0ô ["œÌDZˆˆ†"â«; h9Ä,ÃØÅDÆuDqo©±CŽI`#$‘ q-ª#,Ð/¢0BÌ&¦ÊXÙ8+`†)¨¤±‰$àçr‘ÍFí"0AÈ¡ Kƒ* êÛa~.‚6ÃJP#dÑ(Ï`»EÎÆEaƒ²,‰aÁ"XTÃ#˜Q‘%HBl}Z"#/‚Å_ñ!A,S€Ð‡ “ëïU?ã·_…þ±ê)fÝnäÕ ¤–å4N[bŽ®ÞØ þÈ&x}»Îg#$v*lß%bá'+e\ÖÝGðp18¤OKÂI!ä+¹؆P‘ ±4¬Hq9:þ‰@é¥[¯/k‹À¬ôÐR˜xN)Üž÷ºYŠ{;Q#$”%66µì·5²V±«|eY-lU®[W6ɵ\ªém^¬Šè¯&걈QHÕ A,U gE&ÊÊ šâdMñøWÑ+:G9¨&B½8ÐT(–¨=õ)¶” `ànºèû±^ýË7èÄx9H¥¨ÒTäñ3Äß“³¡x€ltH±h<û“yñá ·ñ®D¥},(gyKáØâZŸ\¬xÐt3Ê}^7S¤›éZM“hÖÆÌ«~¾·Ä6’áà8øòS5pÊzøè6ž#,Å“È÷ò«èÈ¥X¹ÝÉ£@Ǫ«ƒURRÊL’HËyâ©%%¯…B“$ç‘ÆK²µƒ¨Ÿe~[x”Ì#³6>WšÂŸšqÖQ© Bƒ¢#QF‚ "¬T&ÆÎë[ßV¼þuî,mk@‘!T#KåmiÎbo*µû(u㯿díêNðTE¤*«^˜ÄU…ɵO%¬–!àÌ7Á”\™•3Ä1Ç=t:íß)‹ëÉÆE%B*Í™ €°AL éÃÓ¯t4˦ºî‡òõ½–¹è9òè·âŘÖ%•xÒZP²é!Pn&a#$ Ì>~˜rÛÇDÓŸ Ú#$›iÐwÆ1$Àhöm¬¤y$#$Àå²ñ[¥LÕŠuÊðÍ}´`9T…@E¦Ȥ B"P0s¿¥*Ι4K¢R²E îLŽ<»bX=•—ÏÇeítô@C"Òók€&ôo‡*HÌêÙ› „#/3¿úߦ+ƒ©ÇÝ(û,¢eSEW‰<~(ÇÙ„ =ÆeÆFiå.ã®ÍWwJIb ¡¹Œ¼E#/€°;æ¢ù„´§ÉΔ­Û^MA† ¹ð°÷ gâ‚T6#Þ4·•ìÅì}ZÉÍÀÓ0¿N4”!í#/sm àù*h•ô©% Ö,‰tÕ&$A"Çq„æó6yGP˜¦`o£Q̵‘ª *P¾HŸžÕY¹k!Þvf;÷ykz¥}ÁÀ¢ÈÝåUøja¶ûb÷6\v†\õetoÄ “ -©¡¿‚ÓA5@ÕÏ>§Î`äÍŽveÅ#/ Á€Xõâaòݳ¼]•èå“\ºHÜçw9wÚ}UxѺÍcSK)áP¥BÓ¶ê1º#/_*¥ˆ·›¦Åˆ/õ ò><8ã'zuÞTªšSC<<#/R?ŒÞÀÐÂØO£ÝÅͲž5N¨°:9Å.Œ#,ÒŠ®ÙïîökŒªwPSKF ¡--ª%À 6Ô¬qÁ§…¹1ƒwµ×hObCÎGiAž‚ÍÊß Ù)!,mí™Ú¢å~Ù P0‚@ÂMûuÉl*˜Þ'|<äÊ„Ô¬\(Í:ÆØùÚÞzDÆGÐÇ(à¥#/¨°\Œ„‚R…#/„RH u5׌ÅiÛkÅÎÐõ£§U›žÊí|¨÷Çy|[øAÚi…! žÍu[A‹`å}ðWU Ÿ/ÓœO_¯Ø½kš†žV½xLÁÉÐϤ°ÒÈ0,16ß#$=’ cU:çÙ›ëBûó(ƒÒ¸#àÁÏ#,‚™©Tomäá‘vxûkß¿K>ëU o*&L;ÁÀŒÖ.$ô3ôÌy£¨±»ŸÓ~ÐÁwbœàu ‹¶61 9Hg CA¥Ð39J›‰’=ÔU#/µ²ÐüK»(bCÏNJ#/,YpΤá[¬Ã(î¾`pªHÈA$…á{{¿Jn“g@*o¢"3ƒºŽÜ”… ¡ƒ÷¥Ù#,“ã±âcL¸¡B™G‡ÆˆP›#/©ÇÎh@=ݯèv _†—DÅü£o—\¹c\ƒûñGFø&l.o6ÈêûlinDµÄ ®ÌCÆD ¬ïÁKùÚd±a쪇3-”“ö¡UXÐ#,Ó¯fÀ] tJëM/”BóC]™éƒ¯•è×Ãi°‡^=Bå#À8“»q$þÅ·Zîez"ºî<&ºi`4DvåÐ5ÊŒŽ³.5ÕÖSÒ!1ÈÖC@wÄö2•8Äya b뉶sx£Ku–²yZV©k[UÇ(Ž²!œ„³RJ/zuâæYЋ-ñ»®ÕËHÊ&‹IâݶM&L¦Æóµ½Æ-zm}Õó:÷ËlT¨U)Œœ±big}Íϡе!ÏfèÉ NR† h NíÞÜ9cX—³•ðµ‹l{¯SFCá\ìQÞ=[‘é Ò•vIšp¡çe§}Nõp {žê¯ÄuΤ]"QzªwJ"¡¨½@å#/w›‚ú®éé­úŒ#,?×ÕØdH¹ õFýÅ ²Û7ØYÈ2bJ¹ÆpZRþ¯–ºlŒ à–?0îß«áŸ"“B“úŸ–óÕÎÂÌ¡âÃØ€«!£È*"Gdµ`ýt|Q“P€>¡¸ ñú¹g«î˜í£ÊÏôàí“îJРþVCãŠ&ƒK[¥n>YÅ•^òYßü_–a‘é±>{µ}Õ<@@c×eð†QK#/-n> ׆‚œª²&‘0ü)ÀxÎúÏ÷€#4º#ß6aèâŸ}%C™†?ÒüýÓ pÌ}†îÑ=G/‰…å2’ ›¿í~8–1q4­–=8×Zbo#錖ªL6wÍ^‰©& Àû>ßÊ»?«öá-zü0¢±•„ÂÖǬAWõÿ18&R#/ŒR"å…¦t¯ñÿŸÙwÃü7Ù✼wùâÚ²ÛÃùNÆtÿ<)#,úÔ0’t~o èuÒ^çÇ›ŸÍãñÕùoC!óŽKýGô÷Êì᳦——Uá‡8XAWüŸú¾_õåýÑýò'øM‚ÿÃýL`÷R’²Z‹X¬ÔZÉœøEE;ò¬é °¢Ü®£:.g©=C§—vC~pˆ„?÷@)ûr->¬ûš†––Í-#$Lb.ÙÂú65x¬Ë …ñôܙɉƒ»˜˜Ú)Z‡¼M2é_¾‹Þü>ï˜,檡)¡>ÂÓú>{øÏv@ŽPO™ø˜í…ðÃû¶MÉ#ELÃHLÜüߟÇÓÇÏŸo£~Ž¦hÖ™Š¬5¦yŸÒ“¢nmoà›t²Xµ2½yÛùï$ót*B’v}- 9Å>aõ=ß/®n²X#/IT~˜9ÅÞÿà#,µ<¾ã0]5'œ0×zŠÓþ™ôÈrë¤2ñÑkp>ÏLa{ª';ï¸3Å-« ”)—Hü;F¡=ššib JŽn=xg®²Òâ?OGOû]Ò¿îˆ6®)!uDòߢ÷Önìaj ¶0¶ˆ>dD \ Šæç#,{%KhÕC[i $ˆã-Ì2•¾töùòÖ@ÙàèxýRå¼^zµŒqšàŒÖýDŒÆY˜1ž›WÞ{Û “wøÁ>OžwF#,=Q”!ðs=ÖúfÅïAÃH:UF„ŽÆŽÿ/^¿e©î¡ž’ªBÒ÷ù}Aqáô)·õ.šWÐÝQ²‘š®ÆºÐŸ]@Ëý>lG>|¹4™`á?™¢°]£Îrô.Ù銻J†F¤Šý/*èžôDÈ‹‰°Ï\ùÿtýÑó‰²À×Û ïR122ûÍÛx{1ùÛU]%®½Eh‰I8 NZØV@O𓃭õlë}C»wÙã·ãþC>>mzs<—ïŸw×ØhD•Tô\vvèìâî~ƒËtý>Fxu|Á¬V’¹VLöÎ0g:öñi">gØÑB™ml}<‰Æ-ö_Ð^ï|yº9yÅ#,Æ¢¡œ÷>:òYžë‚•ü™™Å¶¹›c Rž¤#$íëæ#$tëéð²@¥^¤D+wX_-~oÓó"aÜO“Ê‚Ä„…V7’ÿfþçú|¹…ÐÃó±æ¶¿»Õé%ý]aÌW¸³8+ùÆ~Só<œO‡9MŽ\nšþzöÊ#§X°ç—oÔCŸ3ä…ºé윋ç¢1¨al¾Ÿ}ÁÚ?%úÊ9ÇðíäôwðÚ!ò9¢½{øSÏ[càOò‘ë\_ä—#,¥ßÀ¶¹•Ã+`CšoíûþÿÓôè¯Õ¯Ž¿žk·×éÝW˜#=§ !¦eZ)#†uP}YyhòϼMnŠý—KdœîÃY ™Ú½¿„öÑû½çºÉèpë×â<þ>d©š*?}ÿ¾­#,Nd*ˆˆÖTH9àèÙrÀëÊC‘ƒQ÷êP^дÄ£ýRøú¶îÕ!òŒ,OG:«n»÷7WUŒ7ª\Ü( ð‚.#$2&_®œ\|¡´š~Ž9–±1Z#/½•BÀA¾ïïE7)À´Æ°eqYhl*B·IÐÃpÄ„ñù~Žg_ê+ÀoåÍÕ§“æ“#$0 KZŠi]}=ª½fbS0Ò˜¤KUƒÈ»Ž}(•…UH°VEBž'™„Ñ{™œ@˜¶ß£§;8á!œ¡£ù³dÿø¡Š”­ïð§¯Á>têj½¤ˆîöÉž«ŸÂ÷ÆÙ4û§½’Ûðžt2ÆK¸îæÕšu–UJ)ǽ¦ÓNx¿.ßÌϬàt„€pq3 Ì™‡4´;oƒŽ#­•VºV#¬?Óövfh¶ˆ=‰ÂÎ߯ùy°¹æªcÖ}»`aŒa`¸â#‡hµöùûz'¼’§âýçÙøžŒ²2.þ}Z=yûǯwè_½T?P^0ûgŽ#$iÄ#,#e‡bÔ۞ƃïB¤3œ¡{æa¾û>Œ韲½Ôœ %2¦¤çá‚?Ë·ò¶Æ†ñÌš5åÃG8uü k/3›¬EeÙ˜>­i GÊ`ȈtÂÇ5cUh»é›ÄéŸ^ݲ»Ê#$0 1#$õÔùà7mw+aúôù=ÔöòÛ0ˆ2 eÉQ[@ÿ¬36]ã ò³n—:,üĆdp­¸_®”dMZ€P‰(ïêÃ0Æ#$€ø€ïbŠýÛ[ùjùCGS#½`ôùÉAô”‰ñ}H½\óóP GÊú¸JH¡ o|lüì3œ§‚ÒŠáë¼z†æ³Õ/l:C]v±xîþÿ̱šáxn¢%ÎéÍ8ñ Šó¾sz$ÓáªÝC<æGHŒKŸ£êsq!Ym*Q¾’h±XÒ¬1‹ààº\Ø8(8(É™"‡Åì#,E(ÏÜÐr²±m«Z¯5`Ñ[ˆs;ž<³UUâŸUÁ?ÛXÍÿd™âi)•ç¨4bºÛ×±ñƒo¶ˆIl…éÃí.ŠIhéz¼âê“õ÷½:+Êöö¬åú¾7˜3*ûKCHîÌÂòE¦µcÉ}kßþô‡©œÆÎv‡[>äo•òU7siˆ®ïï·ÝT"ðôÉÞìtK~÷Š÷p²}0â'RÚ¬Äè*ÊÂxKuèXêI¥–NÌø>MÂKÌt:SM’ˆUFA¬ˆW•é*˜”oØ£˜ÑåBâ·Ä>бå C¡0¨Ì 7w˜è™ù\3è¦çåヰ¹±µy¶+ŠÂ0MÇŠ¯®| #, ½<‘þ;*¶<ðVüwŒ×ø ¨9ƒÄÔ7ƒ‘ºù»Ãh ½Gàh)\‹`Ö<øˆ-ã¡lÕ]EïÇ®ÎZÖð™[¥•ðRӇºyLâFõ3úõqµ‘ÓÝëßhsq8½t!×OHalì«Ü´iXE¦ë%qaÅnúÕ #,•a|î6ÛºBI¡ö ±¯Túܳþé¸çK‹:ÉrÛ⬠#$Nb Ü­6Òä3¢•ß­Ù#/¼{o>ZqAœÎ]Ýl~âS#/ºSzvÞu<žêàϬé´VrsëYêäÄîø‡¯¾³Q~Šq.-ý"ŽÝ5Çzλ\êž Ç”ª3N=Ž}ß ƒËÏ2”ñqêvt03†M9úd‚#$HìÈ·(xbq!(‹±û%²ùÕUw{¾»Øõ¯â_¯½¦ñSåáaìÏ–‡š¹Ï²`Zo!ûV#$a…;ª›}çu#/ëV€¾íOa©TÀ±ÉX¤'³?Q£Lù‹ò¢’G}²‚<0!áµ=ÿÞ¨¦ÕE©I:)é—Úæ¡Æ­ˆSí9Q>Ñ÷³ á¿´¹³°˜§ÛӯÝ4p¦úZ†™E9¨‘BKï<ˆµÚG–æµIßÓFùܽ¯®£IlÎg¯½;O[Kâˆq×ëƒí‰ö×6UN_D³ôú9÷Èé/å…TÓ³lþ{îlïÕÄ¢.fÆMIúß?S2øôæ"žâÊØ£²1‹¯íßmaÅÏVümŸ)Ñlu§Xp¡:GI'wÒ]çBF2ÿqM´|"§Þ]Óº-ÎðèJç³OƒYÆ%bc(¿óiüø´ž®ª¹ª¶DÙ¼RѨús®æ…:s ð’‹ò—žbq—Á™•]\ˆäÃíú¦:Óh(r£'òë3çyÎzÛ唵À¶¹ët‰Œ|‘h~œ´EMIÚ±q8ܶ\ºá{ÖS-vº|Ç&J ë›Û@ ……Ý\ºZ÷Ø&¨ê=QˆöxÞ«¦M#H™q&ùþרÝ6KOáïUj÷+Á1(•"ëº67Pʆd.âáUp$ r¢§-2_€»"§ö¢”ù~72KŽÚ'o—_v<Ÿu—“rNrúýr›?ªÎy/YÐ4µ§NØq+}óV³ F=Eò|"#,ßßUGÒ¬ÛŸE§ídœ»ÝÁñÕÎ0ÞöŒEfCe™g©uÏf£û¶¦ïÛm}”Ü}ûpDÁÄeÕí×7Útq~@÷²96¿×n?Öî&*Ú%B¿h?X ³Ìvxd~-pUFEˆsÐ8ú.°)ÃSçéñõ½={Îp¸¤Hdì?Et3éøÄ]úøÀS|Üø$|ó®þ¯ß©+g}cioYæ;­ ª9+óûðǯ}ðûlრ@®Z–ŒÒpÂÀ@™ÓÈîñïØêÀ@‹Âɺ}dEÂ~Ÿ(¾†‹¯ð^_Ìg#,iûäë?='³p{§`ÞÌAéƒmMG,¿òÑAp KcYŸ{ñôy`P¸†ÚsRŽ+…sô8t%—üStö¥Ë;¦›~ŸeÝðO‡»M÷¨&øxvV¾tbMR’˜v­ểÁRÚMܯ­”¼éàT}q§_!3´óôüÊéÙÃHvOÔˆŽ5hd²î!^ ÖzÌrá¶;8¬m#܆ cqÙtÅÂ)3‡‡c#,aU#/%Ì;Kx¢sø²?Â`ÙoL0k«ËÆùü=×#,°ã,øæŒcŽcñ¿áº~r/wÒaá‘ÖiÞgŸ³µõÁûTNŠ‰¾ Ã’ÞsšM¨J磔èoÉÜåÙð™?‹R³Äa~¬é×oç9/„b ßIÚö¹öAÙ®bZiwy1¯É¤¿[=û’hÁïfÿU¿wÝ“»N¶{ÐÔôÖ÷ÅTXPD]Î*çDíCEÇù²4ÇIçIÇÜžvO¸Žûz×Ñëç’cpÌÚUÊUÒ@‘ ,#$•¡ub9’_ÔŽL3Îq‘~‡X›åí‡ã³ñ¾–}Ã!Ù½JNiõ0ôeä(ä‡b<êÊf—"'µ˜g›)£!i=¨^(¤À,„”$ b¤K¢ö—R.&îkw éC)Ey(ëT±dXXy§~Ìv.å#ïõzšÁTS ]"Ñ@9h\m‘#$`OÑtEX)+#/CÕ!/c¨¹!„¼nGóÄ¢«¥Vtª/®#$IÊ/-VÝÚK ÛísN±#/{<ò«ìæðÊÁÅòÌT¤.¸X³ @°ƒ;®#/Å|’ès…q¥^sWPnf[ŒH™èKA¼#ÄI æYÈoÃc¤žÊÊkÓLDX-zàÔ#Ôn¯é‡äoM '£ÐŸìçM]Ã×kò6ßbòãú —="Gîpî–]Cgb¹öþ¿áÛÑ v’ÊGGH`¸éÒ<ÑFüN§ÕÏœ™Ê%?¹vÊk‡°§(âïú“ÝúSùý¥b6Ð`Eáªö<=x[^í‰cÛºœkØyŸÉ‘ÔI$ÿl«Ll­¢¿ÙûÇ$ûzýÑå³G3’#/0Ôà¸@Cô¨è#$ÌÒsýÒ<@¼jœEõ8,‡Ð\K#/SÁ…÷¿îù^¬ï¥{#$ÕöîŸâÏ«³oaõò®¨þ¨He™ã­ýCÊTbE´\RÔØšÒX^µ>#  “(0@$Aï²øΞœ †¢ uÚ¶©•ÈÀ›¤ÖLøãU̼:G릂=âO—á‚·crvx‡åPw²#,J€í^!Ê€»z†r‚‘œvKG—›ˆRƒ ™ŒÇh¶¹BD”è"Bjƒ+;uá¹zCù¿äþîro¯žçO¢8€°€,=¬¹lJ‚‡^¿,. #,JCÏ»&Í<þ}aÂÐðijü£2€?#$½J Ç°°e^'Zá|…ö­~z“ç>ÎÞ6ó;ídÙu!‰5Áăº^ái¡¦uŠ.7·ÉãDfk–¸|z3çs³™D5K±'óS#$öÂq7´ñ&¿-#/SmLzP>:Q8öw76þ NWU¯†ï(¬¿á§sºZO* ¬À,Á]T¥„qX.žSQ%x]}ïv|Él¥סTÖ5"¦¨²­¤®pH–IÃ97ü7"7F~Ÿ£‹(4µg7½ªøn‰¦m–W^JNãgɘe;g•ÂTüLìq>ݯ#¨,㇄Ž0?J £ò‡¸›¡NExÚ1wð2˜½Û5ßU«j .%`ÀwÒD<ò¤QÌE´Ñ;Fb“ÃŒÂIB8â n¨X”¨Þµ@rÖú]Ñä6#$ý3TÚJ#…þ|ÞU#,>”ÕÏIbóYÀuîc¸;r²E¼½üóåÇPmSÀˆ_¶v?L_"'(PwVR«6ó$¾ZgŽˆöWG^‡AEÏÒ¿}J©Ÿƒ#LüzÔ¯—›ýÜèô´Ò¨õ¢g¥CÅ™pùŽw®wвjš%9E Ñ­Rnæõ‚Ì#,;æ7ï Þ±¡ÖºkX~OÇü9Æ8XR[ú›¯éüTyd³­' êóü£Õ§qøÖ¾ë«õµÏîþˬdF‘&{qÓ>zè^Y«äßäxÆË9m°~m[ΧìÔÕÉݦÖÅ•øuYÆÖ"šã9gHXÊüò_LáûÔŸgäšÃáZö$¬&êÓ'윇îÇ•·#ž\ÉÕµÖ+£ùÓ·i‚ÈJÛtRïYÆ€epy”î#U$ˆF:`óFUŒº\£ú»x˜á7=Z:pÆ'I®†\f™Ah3šE• °0õ\ënµœìK¼‘Ç’ÎÝêíq tKD,€Í…Ï•î>r‘Ìê önùg ŠÛ¯šßºMÖ¡xM­ŒoLÕLÉ·ÖãÙl²[ž<«½¥ºá8¦¸ÎñGe£q·2@¶A4ÃIX¬ÌÄ÷b7˜4‚\#/ÇRuãÃ3u·gÏ\Åù¥·C~¨Ž_º¢ë_íã0Ï€º(/×tséu6E«¨#,KÚÎÔörÖV˜ƒ³LZ#,Õ)ç®ùº°E­óg*îmç=ñ«­g¸ï·ª^ Íâiöó[­a\Óˆ4×Y\ŽÇZ#$À¡(ÙN#,E8®oPÍÔÿ’ÙJb•‚®3Ó;¥:ZÌêT‘Ut%€&%P€bÆý~„dôôê¤âó„«¢oŸÆ:Y}½ë‰ïÄ’LÕÀAï#,|°e…;$›ŸÖÈQŠã‹úÞTD.IŽNØ$<³pøðñÞ! ^E¹gMõZ­›§M¼3ƒ;o· n=z¼î™¾rø¥‰õ¹:õLòómð.¸ðç[îÑȇ!2\DCí¨#/"QI³ûï»n±…€áC€‡€lgû¨Ùmëñ ÷‘øÑmÃÌúAâ`­Œkf6M¯³±ìÀwåïiT|–û‹&Ôª ²šö”#/ÚZõT4±qeŸfFôgÃüÿEËñ–å¯Cæ“ó|ío˜§2>¡¨8|}gGöü¦ßF.#`M¥Ã’¦yŽðétÛ™ïÕÊ‹zP­í0wN„C½¹¾XÔÏwÔú±ÁÝÆᓨuôpd5a¨‡è_²#,´ü»³”#´#,$‘Ì”™¤Y÷䦞ï\ëí,*YÓÄ6©]#,²^ã¦Xáž®ì0iá¶ÁɱWI 7JÖG¤àüÚ¯ŸßôŠK[Àäëq@ Ø îxÜ.Ìi´4Û{WÙ[dzuN"Ū,vÚ+ó|þ­XÝJb Z‹j\æÌ{‹‹ôÀ+”½Îi(sÕ#–n½4ìØ=Ÿ­V*ª1§ Na¥™‚ëÂLQ:€QÚ×ÜA%9¶HòäÂ3Û0vy 5Ój^ð›$2}Ãu)-ÀGŽ¶òye”„0àÈ 4-šb»×ÈÓøí`Nà+Ûbv‘“^;QÕØÉÙ/,µˆ±vî¿n[ï‹ðiº£Á×ÿs‡$PTÌ.}½í*©AÈ·#^ËRêœ%‹¢ð¨¤ Å%kÃ’…Õ„t½ö—¼›U±G?$ ŽyâëòÀ`lA¾ÁÙdí:#/_ Ó¾û´&¸;¶§´ñ,‘ƒ«hò–?½FÈî1˜]avÉÏ)æ.Ì€f,”¡Ï—‘é–‡jµc¶ð5¯Öý¦üLïÏNæ’Äaž"Nk32‰Y,)š‰Pc!ƒóÀg(Ù*$T Èœ•ÔÁ§“z]<ÆíGv¨'È9þ:ÕrÊz¶ƒ«kT¸ˆ#,,3!s(PiPÚë37oPᙌ6öŠnä[]fx» Ĥ׾A¯òá#ÎŒ'¤é=©¼ô=©$“õÀÊþy 䂶@\,äD€3¢8†O&Œš¢,ÃV[ãPYƒ¬‚()qSsã«É;ý´õ-‹]Ž]·ä’ŽS±"õ/‹™¬0¿˜B'ÑsÁ¾Wë$Š“³m#/*ºû¢üÔhŠ³F@šÍóA#€¹ì{Eame (49Pn)Ë›¡÷•êŠž9Ôï;ú=¤Õ7/Ô¨¡uÌ4œé{—Æ cQà–›þ3ÜŠo6ˆÄ)!Í6{…F̯˜Ðÿ(ÊÌ—«@ÚCçЪXDp½†]¸jÚ;]§¨[n@-*à#,‘×YŽÈß»î#,[ab¸@©X÷VØo´ÚA!¼{JÞÖ3È8¢(kHƒ*ýîùÐOwhð²§Ce/ `3¹Ÿ5]«n0³Ø0•¶9.´X‚‚½“éëﲈú-ضsŸ¤ Š¶è‘hCE¨j"àõNª7èÀu4Báé™8:+8¹8 ŽŒŒ“mëÃCFتs7 ’ž˜0x`kE J—‹Èd#/›'xµàÕ¹ˆ•²êw/Îص†Û–Þ° „†£"::Ÿb6ů}’ˆ°Ö(§·º^Ö(ä¹Øf¬DQo-×ç]Ö^EH/«A_¿8ÍnXf¸¶›Ô‹oBR#,Æ[áÙ0÷„bU“8®H’!̶¿f;l4(ÉÙÛ¼WvžðΔ"oí?oçn©zh\.Äe|ÊJ×·5Dé(z#, Ç=µÃHéÑÃ,mÌ\Ém X@)¿Cl@-Üè%<¢q¤^ciÎÑ8p»}à©Ì}¤ÖG0)%µ¾=¼A2þ%‹qnž_„:[õ¤û•cñ³#$s=âu¤Do3r"rÈ ò–¥;Íbù¶ëðzàUö‡Kl4 ²A.з#$¢ÛhÆÁæÜ³Ý /<…c\q±)i8VÜkjeÅñvØ ˜ØžZº®¢k_·\ÂýHÂ5ׯ[ߨ`0"áDtiˆLu”ÄJŒ‚Á£µéhnÀ>o:/¬¿·Êœá#/El\¸`!‘$ð঳Ã\¸l#$¼"ˆpáÊüf£ب·#$<*&ùÜÐA@n~~~·á<8œ,¼[ l#/ È·²"{çvÊŠÎSǯªá«Þ¼.Z¨JjY ³_$#/·Ôºšé2ߟW5.ù­»Ióœz)xwò–#$”Ùý^­Ÿ¯áî@ù?6y9ÛërýÓúD4Qù´( þÅ–‡ÞvtŸ;#/%lU4â<¨$…b|®€…P°DtªÝ”(Ó8ñ'ŽE©¢j_åaíùº‚:ï?T´Zñkì;Ç ?—Ñ[SÌç8š†îf#$>øÏ·rók 04;Vv8ŸQ”ë»6~Þ½^K»:³ãù–—€ó‡žXŒ²‡òíãúÃð…¡¼«k¥ž ô"~Ñ¡Úp뢓µ ŽÜ1îgc§?×UU‹}¸ÿQ¾|½·ûîÍt#/§YT¢‰Jœ0ÀÇoõ³Ý_‡ú€øÛôpÛùÃö|?\Ì“úÐÿPþ• P`f¾FFpÛ™þ­¡¤ÿj’2Oïa.¥P;ŸR¾ˆô°‘Ö.ðŽ°lh° ð섃 #,§öÚ&H™'ųþV~òÞ9j{{,o>¨]¹Û™a·÷ÍÝ×MKpÿ]@£ò œ€îG!À1åÖŒ/·§q¸TÑA5Äó†#$`N‡‰¹‰^¼Í©=¾(Ž#,7zô ªíHaÓš7¾¢¨…uEú£¡¬×@¶`K]U!þÎ!•ÕS¬ |æ£Ö=¨ìN°`ny{C«œaï÷±ô¹?Rû>ÓEAÐÕ Ob;"µþèªXÀ;`]Áñ'X™¥–‘Í…î\ý×ÎÉ5#$Û?[masö>¼PQCPÕ!ê9þZÛ™' }«Èu ÿ6(‚nüßʺŽþÎÛ]MÉÎÉß„ nöuOõU¢UÙüqÓž Åš¤-ßë¬ûAs«_Sõ=±óÒ–Ë#â¶ðïOPÇ)WåÔÁónˆ8½€6ß:ÂVW‘Ò®wúðõý_¿…·rõ°kmd#,š€öT$híý¾Ž³ÇÜëÇ öaç~«V{sãùç.! ÊLRª³RÅßráõA›™£tKåŒ_"tÏö¹öûO¸4Ãø™ƒ2 ý¡¤x‚+øwOØ\œõÍÚÚ¨´f!f KŒã†Ýø$×HÝæ,#$?ÃP3r°k#/'ÞŠq!ÇÃb`Ó˜ZŠÅb›Hblµìž@á»*CÙؾæÏA‹ûÔ0é5ZìÚ ¹'¯ãÖ@~n€ðZuœÀ໎}»A6-—ÜI™¬ukFÕúPÛÞilý}Ç ÚyX[" ÝK dc',¡ ÂÖa¼qô¹í. ±Þ´¥Y zýe²d E9‡;˜‰Åy²$s©V5ÅظpM¦ŽIÔa‡W•¦8„½CÅ>Q~ô‚µ#$ç>Êñ½]3¤Ÿoع;¿ÏãÞ²GÒT%X{<‹Báß5&ìó ¨TQÊ(ܳ`cÉ_Ú^úÑòî„ÿ8ú8æÁÀH“_²6£áý,¯ówßGц@’V¨¬ ~œø;¼ëû¢Sou.m‘ ‡i#/⥦Y…Ly!Ô’7÷¿ÓŒÉºelúÙm3¿U¶Í³>Ú~wÀd¢³’âM†#, ™’Hc÷¯Õòöc‰ßIJÃÛïôйUï·Â¿#/j+ô©ý•²ª0Ð|£çHB`,)$"ªöGª¼ O„$À<ÇÀMá±Aª9Xòü»pºi#$ùL¦×oá‘ú$ÿ7²7>¾­è§è8‚ŒGË3S¡”hÃÃÚKFòZA’{Æ“Ûàmàèpˆgø~Òª¶ðûÞ#$R–þáNâ ’©„J€—^7=fÆ÷:‚Jg0:àÿÔ™à͵.Y8ñ¯èyàELajÉv¾zL^àÖšÔûž¿Ž‚ÖœtˆgxÆ-Ù$°RUURª¨é­VÃøùò“HNþ9Ï^¡ô:…Kõº·\?ÐzÌw<©žÐÔó×B2 mÈ:`,´nw<fÊ–çñΙSnÄ4[V –wÇÑOÞe³Ì>’Ÿ™€…~'öÂNf¹x#$‘ûÿ·å¼íŸ3©à%,Iü†é#„—Sç8%ýù Z`¤f½¢#/1zøŸ‰ÆÉõÝUê6—ï(T»’<´¼bB‡ °3# ÿÇãåû8lqñ£íCµûOK‹MNºC(KDfÞ.— •k§Lµ[”1èì@.Œrþv‰E~yÏ«ÔÚ±£J"ƒHÁ¢Œ^3‹«ÎsC˜Ç>‘Qik*,@¢#$há­ Íúwëص&&ç'qGÃÈ1LȆb:‰¨!ñ Ëìû?å䆿“óéÚA ÑCLŠóêSaµ?7 z†G:»Ct²å%¨¾´#/À¡Aï¸u†(¨#,Íh#$…ë…ÏSÆE8ΗßeAû•05¾,>Ìâ¯"öɶK‡#",Ý#/jP#™SpŠHã¡M)ƒ@LŒi°p`vñ$íî+à1šâ@ø·T‡“Q#/D×[ŸÛÁWØÍÎ ×Êv „rž“ÂÕ›C¼æJMtàk<òJ1.¦ Ba¨’Dp(.D?3ü}?Qöuì¹nÛÑù Ä.Ñùò`Uq’’kºWú=xkÐÛû.k§¯]RoFJM3"‰1Œlå×,’ÃWüÿšæ#s»%¥Þ£p‹LÑ+¬¬Ñ¬ÓÖ™Ô!Ò>¬ÓÓ’Stnäl³+”¤CEœHëÉ$’LÕFšÅ&*eÖ¦¤´µ¶ÓÌÕÍYk5˜ôÊÌ #¯u uë:ߘœ)ß¼: o-°‡.ûB^„CŸeK&²怌QHKõy§-q-ÿaóó]¶d>a؈ZjH M)ßQl‰ÐªïVY¬$ˆ €r¶QI´|àÉ’tÿ»n5ŒäвV÷ $“lCÆàÖRSYÛ¢e{æeâQ>˜–—%M+ô¤Õžù|yj6²ü#/|øÄã¬óŠH§ñß³GH½æE`}ràcè{±S`ž€Éþ0µ‹67$r7Ý8í¥0;6¦æ)$‰"ÆFÓôߎºq›µ)¹DQB™H1U@—øöw]Ÿ}ýåø'iŸÒûÏ°>–:¾ïÀÇ#,]qÑÙØÒJìúÊÒŠŸÌ,,ýlbÚ .±}âBéõÛ‘ÿ‘©¿Lô:˜"yEó—ï=ݯ5OoÌ‘B%#!«51CfÀ<挷DÕq d#/b«{³RYP¼P %(³*&'åñú¹ókˆni]º#,½&íëì‰ÀÁ~Gß8ÆOAÄ!h(¡£q„=Òb”-?­¶)@(˜ 4œPn#$Ç—¯¨^«xN6#$ÓhvŸ]À/Šè†!€Ìˆ¸YúµïÁSʇ#@#$„òêìôɵÇù;ÎJä[ÍvñýÙmÀ‚ŽÑð« Å'º¾»TŸ^‹^ –ô½B)gÑ@‹Dû#,ˆžV8˜¡°XC—¿4׃"„! þs˜Cëh;ÿS‘ÃcànÍ-Ðç±8Ý×úŸ¬ë>†º§(ºØÀÿ$ý#${zûÓð7rð÷#/vR‚$jèîcáØ “ŠQ¨~àñ°E ˆ{¹ô®ßqä­ gÃämÛÈÜ5gP;½_gaRÖŸïåØnP‡ {{¢BÁdŠB,ƒCí<‚kê :•þS˜\¹A=¦%#$šüt¹Üœ»3k»€¨#ä8!É :Pdñ‡_{Tý`T>¾®eÿ6>ÂÈWÄš¸/®+ò'È}OªJu«í/UP@,#/Т„ÚºM˜Óç!w{‚ã{ì@ć)#,dãO†Xª¯ÎqTòSæ ·õè!V+\ÆÀÐ’#$ùøþ•~ôŠIõõ‚qÖ¡§o2ž×ÊQÕæÑ95~ÜÍ*4ãF¸µ™³+d=Ècs:5çR'~bwª WËÕ¹a‰‚¸×ÌùÒÖI˜nßxmÓçé¨`DÆ]ŸYUûØúž d“ê¤h`ï]ÁÒÂÓy@§< '#$±aæZ‡.C³¼áùŽ.F%%  6à^¡x<´¤>ã%Y½U¨ˆÒ£å%MÄ5OåC*g2Gׯ'– hJeþšTN;;Ô(q Iíöýòˆ‡š¨ŒdEQ*BÎ:½yóvÚhÌpµÖ-ÈÛ7’-Ì%Îç¡\ÃkêßêM|ø¹L‚*ïâ<4™aƒ"H,ŠÈG@¡$´ZÌ«Fþ¾„:¦æÖ!bR%?.'2ñ>q®b•JÁ®gN€‡Ùßòg©ÄIâfVOPu«Ù»|æˆ+âƒÚl5vFÿ‚[7ˆdNò›UJ/sÃÝõ<ä}µûôû<œjöå%fg„f)_­oèì±#$üœh‰¡É?Å*(ò©(Wþ§PÕjðÒ ài‚¬é´|1rFã6¥J!*”•ZFá«ëéÕÛ<ÎÙ;'­÷Ÿ#/:ÔÀr‰ÁÂ"ýy4¾ƒíB'¢¢[ú>‰%膶ÃS#,beìv®ãG¸ˆköÊ=€Pâ±õÁârâqü?#—ÛЮdðSÐEŒªQX% ”Å©ñSÁ8Ÿ`ý¸¢äCuÀì;)N¿81AÈ£³‘:î›™ëä€ÚäÀKJýœïOMŒ%ë‰]©zâ%‘O–£w¿«à|Ǹ¹`±bÁ0¡P´pú¿´ÁŒû%hÑm#/œ£ßåÏ—íš bèíÝŸC Ð íg…˜as>ö‘êšÞ¥Ü¹^Ô[Ö‚1.?B1*g2µ#$ÒI,Mð¼0à8÷2$° 4ªÆ@R„Ù‘Mc& Š)ˆŒ1rAH1$Œ‚#„J*"9.Š ‘àÁŠ#/€H9¦ !£R×àuàë§ÛÜgîBŒÈØÄîïÂèždV2I ’À;É$+#,€ ëe$Št¾Ä5ëO@~)Û´ÑLAGÓ¨±,”È3­ `Ä#ùü·‡-‚×7Úœ-kÕq†#,¡èöÄ#8­¿T$¡5ƒ÷ÜpÁñÚM½£E‰LÊ#7˼Úù(×5^•ÍÒ6µÓ#,• ˆ+-–ÝמeÚÓË®x׆±Š»ýÔà_/?žRÿ#$7¦áãYõùOõ¾{OX%åðºçíf ýd€K^“ÜE,äú¼žHÃS­#ˆfi‡Y±ú´›!úA¤S³W’×·vÅ3XÖM]UÕ|%­$hÃÊ6lZž¦wäD9‡¡"‹Y à¥äò”]wñuî8IG–'3}ç^Tòxà…¿–—ˆì@Ó6îêÚŸ”ùÑI8Vø,ÝØ8s¡åY½!¸£¨È ëØQ³²![G‹IË:ܳ'ªv[¾vÖä6â‹°Ä7L-œ*c+éeg¯ï³×Ù•’uÀŸYY”˜’ç¼’'ì7KK„¦((¢~õ’§ù€þOSèÀ_x´­y{ýÜ;ýϪéõGùTHV¹¯Ì7¾~ÿ÷=u*‰ ð„Œþ”MŸ!hU¥¦f7¦L0Ô…áaBÔ7¸£ÜY%Y$‘÷¹êÁöï“t38yvkR 4µ€jbA Ì©hxÆÙ9I$!»‰ñáE!ô&ÀU±HèQ±ÅÅ åÕüËÎ2 ò@5ëR€Ê„7¦˜ X>¨ÏW·ôB¤´ŒÚ{5#Ä:Îä1B#I‡W.®q)c÷QGhIGZOÂHCò†/Wj¯Ÿù!#Â\iO#$²…t~àŒ+@ädæñŠÈÆ(),îg± –Ð%ULJšX¦E¤459y|'Ø—Ø#,UÇðAò¿Ý…#$oP–C"?”ŸôgG‡ø„©ý¿3ãú àë,¦¹1eA•VŠ£ÌsÎ þL)ʺüöTâ!_Äž©Ú žy+Š+.‘È}l)2_Rp°Æq'P‘&1\ÆÊAŠAüUüR"àü}.ô õ>!]ݯL튔zÕi¥‚È!qp0>ðv…›æFØEqæsÉAc²áª}PºqÛÚkÜ"#$¹nW°>Çb*A#$uý+%ÅŠ©‚‚ešºŽ³Ž*t _VÏ-CÖ§PuXoz@ÙƧI%àh?MpTÔ#,N#$åeIáƒËˆªtà`x‡’ê"’HœÌ,X4ö¦ÞÿÉ£»Î¦ïŸ¿ïóÇ\ú|*Š&Î'³ eU B&ž¬K‹7æàÐ .h¸Mó‚vbÁý*VH¼Äx™ŸyŠø–J‡}·¨O_Ë¿×Þ[àûç8l#$Äx‡zî×m|m2GMa˜9*ÐýdTÔgzr77F$#™y¯D°Äa#$¥ q7^¹ÛôBzÃÉä¡ÛÝijÌ;1#,åÜLIªÈª¢ZE³owup8pœžÍgY¢0‹° ”#¸þH~'׳•A³¤ò}î´(Êye]ûÕ1‡óï;Æ/¨}`P>iwÐJN§¶za+8$„…›gq <.ÝÐÚe²(çO³¯ÏËèì-9}ŸçU([¦ ø˜ã¯ÛýÆbÖxì¤ðÃp[gžý-RÓî&7 ëo™œÿhÒýJp$óõ#$©èTˆû>pºÓ­¡´38…ýÌ\hÏÓ™òÇ™ùôÎj·‰3ƒÏýËýX6vu•Æöq¬g#$9Èpû y„WâêÖÎèVHG#$*ŽTù!DµÄ‹h¥Ê‘ ’"7diz–fì,P4QFvqиè#,·S‡­°CrPm‘T•ðÌ´7Œë2lA.€ÎàñŠ¥æ·¸À«Ü]œÙ€|ÿ2Xþh,†[âH±‚Èíè¨÷PT^ÐؼS›Çµ1î¡È P˜‰h+Ú$l¼Ž£ƒ·ž™4¿OèÛ±À}Z#,“Òº¨ä8Öž2‰Â-ŽEz.K8ZªbÕ™‰?zÊñØVÚ‡m5±lªlÁ#/s‰0lÛ=Ép>àê@ÃYH^Ì` ’HB2øü~¯±°jçôÞ3îÃ"€x@DbÒÚ!Šn°­Eþóëz7ˆfèm–ÝÂ1ìqõÙºÈÀ®Þn]oAœ¨Í¸HtäÓ§àÞ7l»E½6ÿ =^A±¼O›¨š4G$ò…­#,k.תR@Ì`u„’Ͷl؈Å#$PX°LÑE{ýZçÝíÈÝÝeéžyy!!#Dú"·vaCÏ×áèD<¥tµ‡Îô>Yû(}¡s!òAˆbÕ_ŠY áìNÙé>Ïy¼@°÷ÆRûzýwGyÞpLA¶Ïy.d?ÂŽïg‘Eå¨)]þ¸êN<™Áù<bH¥íü÷â¬ë¸õ“Ú‡Êõ«xI–M—"þÉüvb¬c„óÿHXµ¦é“ò¶‰V„žß;;K €©©0Š?ÁR™íÛt¨Åyço0]wK×v“2¢éCt ¨’ s$ý/ô“üØXÜv€råßP”ÐvSÏòÁ¢DGâ‰ß‘"þiµû¡Â†ª>TsÉ«p¦¼è @79NP›’ѨYÀà—ypq>%B#$¨ƒó|À¦¿ %#,{b@¦üÅá¦:û JôÕe\>„v &OòsÔ¹2~¨HÃó=¨·;Ì{wû´8KÎÙ¡Àõ”ÖJ!žEC*#$=ç±Ï÷éØjŽ*¦”¹¾¸{ºzhVš>Ë66"_!Q3’»-õÝvßOÙv¼Š‚©¯):‹ ÕV1¤¹@u~ëkþht65«¤H7?œX“P5Ÿ_ç?ž?|ã×ùS=Œ„[úæ 4äÖA—X%"Ú!HF#,Ï3Ú+žÅÚ„H2Ê.ý—Û#$6¥dߺ÷%ãÕÍæœO—É.Ÿ]ç@û?©ŸuÝîöK×Ú¦®ú2Ãåzmï—ðìQ–¿£õXW/Ý’¢0Áú%!L;ÎuÓ2Ù<¥;Ï6Ý°¼¼N°Ja•Kd?“"’Á#/‰•´&¦¯‘ЙŽhq9"ºT"Õ#/+èAá©…¤©˜¥q„¬©æŸö‰µ?·éf†jBóÌÏë#,‘!S[1׈0µÿ€~½ˆÌPZbòÔ@U‹‰®RcKÖõ`§v¬ã\XÏSô\Îf»Pº›–ô#,DÈRHè2Ñm€ì»•¹#$þv€¬FÍ`z04‚:åsx@â¤hT?Ò›üƒöoªÆÙ› $AfWÈXl^«~)úô_Þjv¥Q‚±FH+üœ"þézÔ12É'C£TåR°_àÓüœÚíýŽ ¬ß#÷}Ü¿œÓŸo³W:õìçƒ ýÇðT–‹%¤´‹4ãS5ÙÛÙ’ÚhWWï¾w½ùO—÷(´sÁ`ûOÿ°ß΃϶uÎöÓùãS—¯œ KÉPÜü\ÜVÜB­ñ¿Zß›ÛYŒ” ¦XC™ïf!ˆÈ(µó]<€3£ß¤1:wq»hi"m$,ÑTh($0á€ÀyŠ#´2;Û䂾÷%þQÜÉêPÒÈ(¢°‡c0…2„Š¿`üx†ì†SfBJAX)úx9Æ$ˆÝWËÈôOgž-‚3‚ƒË¡¤´õ¨d% pNãµTÓ€WùŠ&Rüìfšìç0x鈶Ø4 Óz<üQŠ^;ê™WC$‡s€þïàìÁòé¾dãÉÍoö Mº&Y&\»¦0÷å¯2m“|Ó‚"¤ppÑßíãñ“Á¿´·«üƒÞErØl~‚üºÎA&÷E›`¶€{gøñž þÆØ®®­ÿ$í„Å_X)„=‰­ìz Šf8g:³ÁŽaË#,覗Ø&´6_¬ž²áÊu¬GsÙÖ6—wÌ)¤»¿6¼’)iíÙ•eøÊxæÜö°óÄT¦èÅXÙ÷xUüÒ{ Ä\3ˆï@Ïèk¸(˜ªØPTïã°…äðDçG½#/@<0G{BŽ£|þxùdþ—zΖ ˜øBnÿoöv”„tm9þjP»=R‰7@gòüíÕòëlŽå爵Òy£º¹öˆ ßöC´r¾R}W —˜'9£§×$›}­!!«Øh~Y}:8“E®HòÚ¼#æl¿Ü1goåÔu â÷k‘@¢mµÊ¡U—°6öÈ|0>:(õBî›±lMÜ,©š¬áÆöÆÛ#/J#$øh¨1@»–S{à=N¹QG?7ì‚õèßËæzn¥ƒ&¹FÍXôݽâ6hëq#$—!É*9W¦ê¢#,îˆÊ9Ÿ9p“¨+ïíø5ªò;ÐwBEGÌYgi…@ÍÓúž%½Ñ?Lþ-ý$(èãr‰ Ü¢NûJq}ß­}<…°YŽýàê]‹˜rk¿\8íçÓoSµGø²F^©ÙwÝiXYzÚ%Òz²XêþËÕ7V÷ý-<%-5uùÈj#,Ü2UFf±/k¯Ö;tN®É~‡Ž±îe±»10(7VlÇ-*™ºßEÏp´ÑÔ|ËÐphÔ¼[•¢h)Äë9tÎ&x#]_ᶺgÕðÉxž1#,ëZLÞ&Ì©sŒì§>57™Ö%û¦œ É®z 5¶ †”{ö}/\\_G–H½c¤â4Eû“þÚ5Úù6o‹ÖóQr×KålÊ\å¬P ¾E“ÜGr¯½·çÇn8Å&ðà9;¹ˆnBèîní²Äö@þ'^D.™~™ÂešlËËQª‡MðUÊ|woØWÐyÓJJ”bh©š0ªCj#/#œhÖy'-zjnê¼+Hgu¨•G.,7$ôQ[)>é·BˆjÇ•ïýÃù¿ƒãçî”ý¨oËÍò¨»ôËÕ—tŠŒ­ÙÚN³Gt5’憥p‹kX3ú‹öb#ôMðƇÆ@Â$v>Wß9=fîù½êƒ¬‹°±¥D¤ÞÕe‰‚©è ƒá÷ß&’ß0²G+a/Ów9×O¨Tg¬Ù˜z‡úÛõ§d¿Ï}=Ê|Öys‡gûD_ŠíNï>xD„›ò@ÂÀìZ0¼–é6êQ-9ú­¶bêy?MÑ¥Ënª2 y”#/@óJÀvÄòÇŒÕ}Z̶M¹‘íÏ(?j-âQ£rŽw¨~Mû6€;?èÍ@ú“ó~„êí…-ïTwòóÇdEÂ^î›ávñ·×Ïm¡ˆÀþ;|DhÛ2ç˜Þ½ B!z¢ö”ÌýoMðAõ1žï’›Ë"ýZ‚æ€ã™ ¹ÓИ»tÆ6Jp2O»‘^i„N¨qaHB›8|À‡ùÜq9ðÄëóÖ"oåZe¾Æ$T¨A±()Š›~!ëÝÇo‚q+#,»çœIïš–çiZ~Raæ>ÄÙ5ì2}ø:²E`/xçìïés;hL˜óN%Ÿ"]¨¦b@6B÷ ~ÖZC‡o;0V»Ã°¬žuê͸.áe‡¦fB]ÃÓv’ªfkŽgÆÞ¹:ëf"Q_gêƒù6‰c9vðˆ·jhv‘1³ø8IÛÕ–4”‚‘u3#/±5"çž½š²ŠÄi¡°’¡9q…ˆÝÏQØhHÉT‹Úܘ]VHòçˆ/^Ž‰Š¸&ýr6-i’b:CO#,AÍ : ‘‰Š„†_§5?ƒögBYš;‹(°Oaï,‡ãý_÷YîMÇÕìã§òþ ,,#$‚†APæÿW‘î¿üôr8'ÔZaøÅQ9ß÷ýÞž£~™™œJ_ê€Þ^vÂ¥}Þûu8çDL™AÀµIùký}×?¯ö ÿ/ô~çÈn ÿ”|Ô9ûQŒ[þýl¿l’QqñL1#Fƒù²k]˜»S¬Ù@àVÝÄÈ5q?pšµbj#/vfÄ]¹´ÜQi )1B#ó:Ó÷Ùw^sc™Ð©Tjê1ÊÄ’_ª#[™´ƒ€&ÚôunµÝW€x>ëS¯2èfý#$Ä´v¼†±àMíÁºã²·EW¡6bN¯úíáÜÜ;ù8 ØÓïì½;Ö©R‚¥Þé iUÐ5™æfCS+fY±Þpþó`/HŒAƒÒ©ZªU¢›É5§fC{æÛp”#Xì7óa¦Ý°”'øgø¾Ï»kö!sC@,,©„’h–eï;§.>‘V!åùÏ9£«¨×møÊ)–Ö11;üŒˆnØM‡]M°ªÐ¤òÄ4Ø’µ‘Ä\ç\MPspëöŒ÷Å*„MTâÉgWåÁÜ8I† 8Œ4€@Æ°Ä B1ˆAgM@;H'0|Œ¤3À‘Ú4®úlnÂ>°Î!b+Q™aiM¥öÓzØÔ½Û†TH#ÇX3ÏÕ¡ÓÕXH •„8m¶y»I5nèegõÏkäxÖGãV,€éÝ臺?By÷s5“±rü}ýWº[“÷Â0õðÕ¨qúcö»»×Qfz,îÜ À#,8• B@ñl!c‘JVDVœ4¢ÖH65h.­1¶L´Jˆ$#,­D2ã5?0l¼º¿±—îʺÚî[‰6Õý÷mÉ‘y_¿ü?Ñö·´³Yš#,¢Åý~÷ºÂò±µŸ¿çCMçDuÕüwO5„ü?´å´*IóÜŒø¢1®í»6Üò„‡0È–×å?J¶ ºÚ ŒÎÜuw8€I¶j‘#/ž<ŒBþ²ý߯avìe.vI0„&Ëmš3ô)¹5Þ™·kr5QƒCg`Òðíõ¹€‹ê|23Žfµ¨ªˆ<ÍsÅ'wÆ«Ö8¡÷€C·#Å^¯•ß5JY,mMš¦bÍI±°ŒC´¸¼™7T™v‘YÉÈÁÖžãq)¯—ªK[ª3‰«Žhˆôz‹õ½¦Tuö‰sQ‰¨¡´†µêëe+Ô\›i\¤ë#,ág€`ðu¡Ä¡W"åEÚ9ç±Q‹åÊKè~Íe\ºaðÍzàî"i$-ÚÝœ3häï/á߶Å^W"[ ºí(IsÙêÞ…Îo4†±µÎÞPÐÚ’ñ!|0Þ‡ï5Jn˜Bfa㈌vö#,·ü"€Þ@I¹²¬’K`%¸n¨ Gœ±@PIúºÑ»#í0Lÿ«C§ê ’ø"Š}›•êz2ø³ -…$˜§ú#0f¥·—IšËúŸy”Ì“N§ôCHôçíŠ3ßP}wvÙ.•‰ž#¤'¢ ´‰—ÔOBðÈ9ñ„;Hvˆ"GôΫýHþD ˆÈ°8^ʈ%|8®+ÕSþ‚fÜ® ¬Ž›NßKä4Õ®Hc‘¦vvöe©´­%!×á¬0t¼ôÝâIæÖ- ®¹r#$ØŒ³d;éšÓÂC(åýOAôjŠ…=Š°eA >^ÿ{ÓŠyw¸+ñ#/OÃ×cý°ûÿÜÏúߎ’Ö?áÿ#,11õÖ³^u»Ïâu!D$ )~xHk~?ËjÔüu=K©P$1a2?|U”vvyøpô%P×æ@‡UŸ¼‹ì9‚Óù‡ÏÌ>’$&©m2U)··uüpZHÅD"S¿^!(Üã("—<„„;Ø'¨©!%-zÅÃ+ÒQå`ä>å?Ç$Kµ@©¢Ò(øk¤ žOÞÚÀxXã`ò¼N·Ç±ÿb®9^I!5‡¤:E¨îbUCPù@;?P¤D™wFÄ…²\WUQús=$$ˆ"9ê—) >¸±Š–LÑÔ¤Cj¦àæbÜ žÊCaDDÄ5,Ÿ üƒÔ¬éz}¦”l‘-hF/<ï½ê×Õ‹¢L>.TíN#/hRŠÈH k.m`eÓÌ€ÿkdEººûMðñ•‰û¬}¡Är5ÁY³|„\¤‘9ªÔ;¢×Í…I×âÄY‰9 ÁÒdu²#ó§Õ 2eOy#/Ž#$ ×´”è 7¦»ÙpŒ_küŒ…rŸ=«Ô蕃ͼ@mËN:ôÿˆEô@]2CÂ#$°V HŽ{:L^J ªí€È¡PI#$ ƒ€BGÖâ;Hà Aš"") ˆ¬HŠ4@1"¨Ä`¦óÄ0ôqI=VåmÖKŒÁQ£ÑÆJ>,(FÚZ¡d¤ø#$…em®^)Øj°ÖÒ0i1™ €Iˆ‡BÅ…‘Æêóy%2¿†kÔ"ñ¯EJI1oWvñé¶æõ7©¹®Ä£wv‚J€Ú#ÿE©VF ÓrF7 F£2VWvŽI|ºuº^r{ø«Q†EGþl: ·2ƒŸ¼ØB,$ŒQ‘XPI÷˜ÁÔ}n0cD²¥œü$OX+Àö¾Aà/†7òû—öèóûÉÝÈF’ç}TAìde±§¯ƒg^ÒüÓw<÷4ÅŒ»*Ȉs u ½5‡ $`òXÀwh.Ѧyg t>µ6ç–LÁü€èIo$Y–‰­¿ÕìDÓ§¢×î;om#$q`¢™Å¨Q‘'eÙ##$`H³?§‰•6шô÷aÈKv#$'¤hØUHîjÍey诬·§#g7ßDš˜)—‰’É8°0!lyW8Â&̆Mup÷%$É„‘Ê4D¢RÚí¥MÎf4°¤¸Ø . —èb€RÄ_¢#,ÆànšXo…7k‡½ÿ)RGøB‚¤Y’}¼ÆÜ.z½·D´ yqm(:Ç«Æ'è #,»A#,ê¾êµX;]׶Itî ½lëÝi!,ñímaúƒSšÆ‹ÞûŽÜü½ôÉúzó©0Ç…/Bw¨ˆ–K?HÿÙþ9:$­›£è|ÄïGŸšãœJ²AÚ þy˜–)×FX-Ž£…Dª›'@•Ö~Wëõò(„%Tª”Rvuý!Óro<( ”u šÓÓI¥/g)äâªõ@$P WÝ!Ú ,Í‘‰_5NHò1•ôœä³J°æ[:¡æ„µ Óàj$(/SÒ‰Ç辰¶&ÁŸmüÕžŘ̑µÕr³`Â#/;¼wcº¶†G»² ¥‘”ĨñKDt ´èI"Íb­¶ÉV‹d¢6jÆ’l¢JŒV++-«M²ZIkÒV²2£M™•ZZÚU¶f­‹kòßV$ß>3…¾©Rq‡#,b'Š  ‚‰F@^`{`€oq`JÔðt¦½c7æµÛd[ªÁù°&Ðçånd(`<46:â¨æ¢#,C#š@c€à‡Z*Ë"—슡‚°rb2œÛÃâ|©+âö…öË¡$‰À„ Ó-š&Þ ¤M:Wʦ憒Œ‹@À47 ‹ä çX2ÉW‡)ÓjÝw§®*ˆ»6ªP Z(ìxGߨN{ÒuqUC&šÝ¨$[j]8l JºU‚ôÀ¦Þ»(¾žñãƃL`é*F"¡R¢›ulÝL@T HËh„3ÂtBE ÁP‰'H’åcjŠÕ͹²W+r™°¥L¢©˜5%lTZj"‚€ˆ^gÝ<Á ‡csLšÈ#$ß#$„@ÅTìE]xßV÷ǘü¯}¾gÙíÂÜi¦ÒÒ˜8\"mø#$DÍäAß^Gx ÷]ŠH#ú ‰#$ð¢¤7Ú{ä=gæíÿÝòýŸ£þ§÷ë(>S~ê'Æ0Igwž ¼T)Š¨ªñ1¢#$’Ý•ÁÒh„h¦D"°¢#åUPÄø/{í;|øØÅt‰¤¨S›JŠçüAqˆÿ!5üóÎê)_[Kìë(¼É#"Z õÀç7àÐ$¼V-ÕÜ º0ÆjC¼Kÿr¡ÙÚøô?À&V~T"ì`dCc˜ƒ"(e»Öw ‰§ ;vä>jtmÔBœÃøÞ^P/“ »PÔ÷X ’§Ùl#/“’Ì€þÓ8GIÂk l€(2‚hÒ:#4œÞ)Ì÷ô9|¨ë`ºö”¸¦sz&(ÇþLy¨*_]‡_¯â5 ab’h×½Ñéé}›Ÿ¾¼!Ø¿ãwfÜÞú¨w[#/=÷l?FSÀ¬4ù8|^+¯×ïÑÐ*¨ƒÂ`ý²À ”Œ>·†D=ÇÒFWxч>ž“|lND-¾0M‰Üu§$Îâœ*•Bz 9 ø¯í›»5gl ±Nƒ .[O9´/¶LV8¸æcbÖ¹s²È {„"ÀHD{JJŠ‡¨|CÆŽðí}Â.y!ï¥<ÇÇ´î­I%úú¨OU‚%Çý£úýr†”…¬¦ªŠƒJ5ùj»¡â8¦M²®î×r…%‰5÷ÿ'òwQÀPL• b±`ÑH«šÈ&P P"X€ó²¤ÓéÏv^ÕúH#,ښܣ#$ôÖdÝ×|ù9<]B%²øÙ=ŸáÊAÆù¹ëc‚ñÇ+ì€#%KMà‚å.ð~\ùÖú áDˆv‡èuÇ!XÛ¡X:&+&ÄÁ¡MìÕ„Äå…“i‰lc¦CMô£r{ \t@s•k£»ÑÇKn:v®Ë§~:ÇmsÊáÎ8âŒvÕ˜èY{³HÛ­²T&¹Gnl÷×=k _ÏM‹£¯æhz:®ª0l6·Kê.¾\ñ팩l7<ã™ z àMÞ[ôÜëg^M³µ›W@g#,ñØ+ÕÜìØÁ»ôű©·|ûâÔíF&hŽÕ»(tØ·ýË¿²¿g_Z#/A r"Œ â+‹™›D)”_Dz]¶B|¬CCGÃá‰Í‡^›Ï¯v&Cu<à†Lh׿¹÷8×»¼˜öÃ>övÂãÍÇ…åÛ`FÀšzŽÒwHè[ÈT÷—ßSPKëThVB¥(ã—éèsçáß݇ØÚVŽ{s!MgÀ¯\úÈb/À:ƒ°àeŠ#$Œà´5÷\c½€ #$nEcFH<„$"ëËC>pÁ‹lßØ¡ùÁS’'+ä4è»ADDšT oÞJ-gjŠ$|0k1ÙPñ3@cµÀÏh1E°ˆcãn3¿‘ãsô}_ó2Îú7»un£6­í{Ã;›ÄœÈÕ&„Kí¸-y²^Ìù%­ŸµÐ߯}zw áöir¡sD鿈æ»#,f$MÜç²€ƒ-Ž|ŽB:£‰ òg#/4p‘×–ª¥KD†C³³Æ}|÷É8™˜4¢‘O¥×ŠÈŒŽÍ4VK*›ªÝXÄ÷û÷1è{@R^ܙȂ!† H±’jxçOuz™íéÛ§HlmÚ]Šj&:Æ#/½:}ƒB#$eHÊ;oÞÉÓ^Pz{~†5¶#,èýÌ’ì0.ÂŽs˲&œy#,ª†k×°ÜëÖvéŸÔ|T×Ù ÓÙ¢¤d¡Ê‡)ZRIÖ¦tÔÔ£ô÷õdGƒ]IqB'}º_ |ã±y˜õN•¯&lyo–NôS5@1ÁÁäÉñúïÀ„FE4øïÇÕ×µzeQ ¾A×N¿f-jÚ hœ@ïï yƒÊ±œ¥0KÈç`±j¤I¥iUº«˜¥‘¡›%µÒæÊNêêlä\š6ÔÒÚ‹ÝHÅ#Pˆ+#0+–#/Œ…¡*R`B…¤¦’.£[w#‚â6Qš‹‡n¼BÉe#$HB+ Ïz­ó/kèÑhjkÌ%Y• *H›Êv)¸8—l)³DÃ:Êןg#ŒúsøÇÛ[_³ë«öîOÃÅ¢R¢ŠRY@6’ý…t°2k6ß±uÞÂOeŽˆg®„#$¨‚#$ÆÙCÚ#,ê„lü ú,ûžÔïu«¤z?t]™’ /®¦2‰Q[ØãW:à 4óI¢FÎÚ/caÍh¦1ÁP¡Sš®Á ÇUjÛ Ão©E=?„é„mvïž Oj+M#³P™™Êü°­0#/‚yÃiR5Ü+'°#/¬::ÏfyéÃaã°Nä‚qB{ð;äœ;çÅ#¢*²mck*ˆ,˜R‚ˆ€¢"T¤dP!r7H[,¤ˆhZT"XR‹³v“š¶Šf©àC°úèÏ‚À(¸q9€È’HµE(€’!Òéí¦s­abÛEx4W÷èßÕÙ9¯.y$&;ùƒ¯:÷Ö¶©Ò›> ?KuUÉÔñáy¥}®ïÄ>#/`ëÆ"€^%Jn~M)Œóš;ÌAJýRM¥,m¶&mUUO™ì0{ ˜IˆUíÀVýîgõV®QÇ}¬¼„*Ôz mÅÖÕ C!Dgr0< Q.Gc¿|Rí¤àÙ •Óá€0“#$‹D…Rhj±‚)ëo]D€ŠÐ¾OUBHp׿¿ŸÛÜø¿L(:­È×#,•G¬ú»{xó*¼ÀÝÐÝ%¦(¢?]¾˜älÈh›X±,´P‰s<Ìt¡‰«Î®šåSTÎi¡r·Ó¡Ë ª mœí0ï´ÉÁ'¸hL0ú„­èÇàh”q·S¯Ma†`:µ‚‡tÚ·ˆ>ˆèÇÂ÷µàp„-Ý#/H5AH´²—|Ë: üÚ@VF#,à»o–kQ;Û>]úmtM¤qü:vÃ,1gb†ÚN¿&RI$7ØM£»³½W@ãŽÈ·#,&Òì(¼x„„ !°×Ž¥[ªØl‰~¾b@dŽ“pID›h€N‰@x7 f j2B„º+N„¹Ë (°È îHÈ‹üÞì¯gó›9îU hÀozã î6—°FZƒK«¡Y()¨ìÑ ÚE]M0N6Ĉs`2B5¬¸˜hiƒ"a‚„ ‹=–´G åÆÙ†¡3„ܱ’´—ÌxØ´ÖVé|<¼Þ©·­µn¤i5Êi0K¡ "R#, ±FÑÇ–íÙöíuv^Ü^DõÃÓpJûiLw²HS°É¸œ#,a`Mú| *1{9d_Qµ×tFŽ­ͧÕñ:´—JlÚ;€ÿ02„x2w&usà[ûO(I¡,‹7³ßÙÔm=MÏÄ’ýäµ’ý™ˆƒ~šÉ¹ülpkÚÅÚjem’x¶vô~-í)¥b{|4ðž¾Ä}Bâ½Ü#,#,[ÒÁ×½’ýõÎÞÝë Š4åÔØ•!ÇrÇðég”N;8‡#/0ZMŠ(R¨”NOËÐÿLŠ@ˆÑTèk=þ_^§uö&.ÜÏ‘kÖ2¥Ÿcô¯ÃyOW¼ç¨¸|ý¡Ý¾D¶Zˆ'£i·.†9Yðæ4€Ø1#$§#/Çi¯èóê'}Í-«Qc­¢†@%Q,D(Qï#,"Äç‚ГòõÒ’‡cqÁ“sF÷0nR£dºÆ•Ìhé’Hæ&š4! ¤“B¦——L ðiÙš›,#$!3#$”ó˜,(ÖwS<é½m\ÅÔ´ÓT’¾ZúcLAS#,º¸·GäÅ ¼Ôž%ÇRJôÉ·ÒwXU :É–c7ãweüIÚŠ(AÏ «¦k³L9ä>øm5F½rùSÚã‹w4¾xz8º:ÄòTF/åp8™hþë×ÔEÏŠOã*ä4ÈðÏØh¦•Mµ2½jkÜù?×äÀd!$Fç|í°„Þ4ÏEo·V¿mA%*U¯Ä¹âÛˆ,#/ÑkQmx¨ÕÊÚØÛkQ­«•·5±m´mWKK­Âë>­Ï´¸œˆ_½ÂÂÅêŽru›-Þ«[¤Î úÓ,oS¸f°bÖtlý$úŸÈy¤Öµø$Ê$‘¡$™3)šV™fIJM1Iª-&jÐêL%­!ƒMJ)¢%#/+K÷íÌ2kI‹$¢S+f…2bf™’3ª4Ä¥Céî¢#i,Š‰LRJK(aª ’ƒQiQ¢ˆ&S£4c&JÓÖ6BeA’¦ ÊTf ÓA¦m1%4Ai£¸w$ÞlöÔâ<€¬¥ûB¤!lö¶ø°LƒÞüÙZª¾¦0…»1¯óæ̈þ±Ùüâœ$TnŸÊðÃ9ÙÖ‰†ús†Áƒ³q$¶˜K#,û·m”$L ¦Qmý¥pÄ0#é‘Ç¡¨:÷w›EF£?=¡‰}æÍ6apí´ÛD¹cb‡ƒ‘‚Î#¬N«§nk—õFöqпÈËêÝ{›žŒkùÒÓÃ-Òo‚<ä(y™Áí#,¨¹¿ðýõa‚;S.y˜6åŠK˜ÌO‹}HôÍÕRGàóx¯™¹Z붖º5¶R!M wŽŸK€%:LŠ;eòÉVqsž\·iˆ£¬Ê%x4ûmÁöãÇŽH‰ˆÌwŽ nk‹“ÆK –Œåñá×gÿü€¬í6pbV´Ÿ±­]RKm7ÓÑ×#,í8~æQ‡­ž-wd†*t*. Éns¸ˆ•ÐP;;åHÛ;ª°¾¶[a:y—#Xc~Mö˜;t°Í>ɇ#Kßóúë…ïü';IÑ!RC,7ÑÝRoG°Cíô\C¬í×óéôã¬Ãø­eúúPnƒñxÚ{ÕK±(Ñ;^{²“Ñž§ ü“@JÕäTŸg—;ú܉l‚Š}ù ¶ ¤w¤8ø3xï#,vÙWfŠ’¾eŽà2j$Š£›«‘Œ%œ¸jLˆg’“¡´Ô~'|ÔÔJ=•Ô‡nœÑ]¿º$ª PÞVàÐm:rí£Žý¦ÙÛóÎuÂHDôɯ¿3ƒ%Ÿî5)º‰¶DžO©¢:25Œ+jF8ÞVe¼ÐÛ2jŠPƒË̦ –.šposY§ôq™†ò¹öFÌXÜÔn&s¨óPÓ2ÖÛ4òóc4ÎF¥Ð²CÄÑ£QEMJ5)‹ŒÖ±,¡ÂÛK,™…6®¬š‡[|fçúþ02!ðnÐ6#,ÂΩª²æÑóÄïLqåÇŽ™Ù !¯6teÝ*ÇV#/烨i¡Ñ72Ò;!÷67¶ŒLªL¾t“ÑŸùkhÝF9pë¶À…ø×+iâ5­zY̳Ú~s‡[i¦¤¡c»“Xtµ¾Ø‚æçk”G#$í,íçÖšišºÉWêù6RMªhÅ£ØZMDxé‡== ïYÛ0gʈˆŽ4åç‰2˨·¢%fïlÖg&qz1]:Þ·Œèt“:Óº¶6´=V_ìÙ²„o‰ã×mcXqÁs[¶Ä'ÜFtQ úÜ:IÒ{À”˜KAšÔj§=1㱡Á$š59Œöâ¸:¶­L±¼ow4Ö(qÏ:ß/Žq˜nWd/g¨J‡n2NŸaî663#,G–ø#,cv¸ÉCëÅÔp÷»TQD—¥I@(L˜„™1Žc¬!1áæ[‡#,m&¨Æ3f‡ÛZ¾p<ÂZvÐnÚÄ°ÄŒÇ †Ýà€é`×B&¸2 ZàÉ2D¼ÚCȹiawPPe†#/0¨á¨qL,}´Ô)«)„‹I:m*—ò¬*ra‰EJÅXVù¸Š²o‡}Õm{#)!L±Š1ª¸ ØÙž¼çMaæü:ÙÍøåÜÉ_Tòˤ²¾uF‡Zåͧ)8ÇbÚcLÌÜ¡ Æ´±:Ã)ŠI¸˜+/QŽ’P™6ûDÄ>id›cRNL¼Ü¢îâÊ7L:àêçµÁÓT䱺”׬›Uà58‰³´&#"B\˜7è$i¯ŒÊuÖ%HjæâÞÈTÓHªÞʧd\:Òvfk¬.C-¢,®Üâ’7„£2Á‡ÙÊ#,)„FžyM’aàÚ±L -šTHlúiv3ss4tÓ•§Ó¶ WCBi”´†ŠuMˆ¥’Œ)‘C&Ŧy¡p9ó©3…jR~»4=¸ÍÃ#/Y¬ŽÛëEÎ&)Ä+æað®ì¦fƒC\Ć룻ßÛTcH±ãvšLºsîÉp‘†üÑš¶Ž°nš“U|øÃIãZã±Ìß`pÖãÛXÜŒvqʤ! e“â"•¼ M4–Ø.*OfÊL‰‡"ZŒ-íð,.$º˜På8¹™˜ÄÄÞg}C®Nwk_#$Öò,®až\´ÃãŠk(µpžG†SbŠ©)(ÆùØn»#¡›owšËYª=hÆæYˆ”G“Ž‹z×LTLT<øùkã—Ìél‡68'-#$ëÑŒQ âÔ6ðFëcCìš°œz|íJÉ[8Œê#,9|`5Y0}ÞX®ŽÄ™+ 9€IŠ9gVZMèÈÍÜ …kYªZlí œVx#,Nz#/#,2¿NL$13£ŒPiIÛ+] g‹›w{á=ng|ô2æY ¨ù"4ê@ACñb Vf@°ÚjuLrî+˜ÂoÄ…%êš¡L"†RP¤…¤ ¬#/e±Iu!ž ÕÑ%3ŽI89;#/#GH#$8“,Œcm„‘€ÆÍ¥×Âñøk˜[.UŽ±¥¬Žÿ´©3´›BDv ‡JíèlËRQ]+y¦—"€9 aÔ4ë8†æy¬r¡˜%„6(j¥³„¶"#,.¸ó‘æ!¶ÎÛï"†Bˆp5¬É™¥Ìkcp²>¹—­‹¬%p%R‘êå0ÌDŒi+ fç†èd(p8è; `Èéˆá ŽÄp‚UC<Î;&ŒÐ ´ÌÔéFzñêÉ0F ‰†Ìnéhg4g.3ho$#,†DN%½ C0é FÃ9²4SlÁdωPBI¨#ƒPÔaÂL#/f³iÖÜÈu"èj×3^"b¶tKFÎL¨èˆ…¡ \¾1tÞï‘&€]"ça§Y¨Ì2 ]u8‹|î^áp T:C°=#/è°GˆNfŒ™«5mýüµÖÕüϦëw#,¨@DÕLÁÜ̯¥MˆšŠµ)`5þ\~]áðäà‚b½¥UÀÑV0Á-J©kô÷_Mòæ1 † 8‚##$"§ɲE'êÕ÷›†¥5o‚W[ªì`¨0ÖiЕê#$ƒ»-=Yk8Ÿ2[@™ P‡é…‚IïNÙUI‡Ã>”þw¸ú.„÷ùg•Ù{ÎçRÎZ\ܹJf´o7~²Û¥Ø‹:Âó®_m®P«4‹Íº…„Xó#/Ä>ÐGr¤uÌbt6T½2KÍŽ& Ì»’ÀÄCÈFðØ1bÄêzN¤uä]\䈙¤ë#,õè#$Æ{H¿c‚4rp?Ö‡îtB£É)$‚F;à„!ýöuØU#$(i¡Ææù¯™m~4Ëm¤Þ¥%”3Q#/"ðòŠPÙP9[L¨L) õøõ¤LDÀ5=Y•!&tƒk!kš„àjÊ¡ŒZ\aî÷x©LPð_¢qn¦Î_“µWä#$oÓµe–«ç\¿yS—WwUÙn»³.nºnØ-sd¯å¯5<¿{wdHç }æ£Õ½AßÔî, üŠì(Ì|ÇUGèÆLK¿‘ý&J-Ðv¸¿6À¼#,Þ|=ìqØ<ò/ˆ±'Ü3f•¤Åð#`ÉbR#$¥ÕBµmM¤(Þ.,¡xß ŒÜ­ƒFŒh2!M1X·¨•Rš0rpÁ.]¬é2¤\‹ñ‚b‚Çwê\12H,ëhA(†¡£°ü™ ~Ò!¨=kñ¿‡ÞaG“Á Fö5¶±·M w¿5üN¿ªkì[jm )+Ʊ£Q[FÔIDLMŒÓ2Ѩ(¶ÆÁ_?ÇV]:íà›½fÖj¨#/WR›õôî\SÅwGC²#$š;= N‰"O­bMxZ ²Xˆ‘ˆÚa &Àˆ’"µ¤rˆ¶Ð*Ÿg áiŽó·¹ëÑÐ 0 cÔó¢ÒwL—ù-`9— GœÍ Ø;!z±Q¢/×j,EIr>Ý%Y0¯Èºî @;(96ض›pÌ®²¤ÓE3Pa“ -ÂGJ ‰ÅZLic­$YÄ÷›ŒÆ„B»&Ã&#$Ä%¤/B°‹fR–@l@ÓE`›Œ+K†³D#0þ“Œ¤LØÇq]Ê„V!Îo|"üŽ´´`GÖF˜šhxà›rFƒ‰’´˜0#/¯ÕK{÷ÌoRCŠf)wß„<ÉÚãšÌ´ kœæ¨dÞÓE¸ï4†B«ØÈ4ÇÓ¿nÚá.ˆåÚdƒ’#•u.ª‡!6Ê6â%‰Ø[¢µ¯GIhHCZ0 ´‘4àa#/^pí‰rÂö)„¼#$‘ð`ºD²b+ªFiç<-‡åäð‰Øvø”Ü¢ì’*ÈBˆUŠX.”¥Å¼bÙù†’]p.´Ÿ˜€ZÈ!QY/}€ÙC $@39$°GÏ#$3^^UV©Æaáåm7Ó3ÃF]œm‡6±Ò~R¢°kLü·p£ˆ7Ò.Fjk“‚¶ˆÈÂd\}™GÃ×\™ò)M9"˜H_S—Úmé#,øeDwφ%5†îÑtDiÞœ4ã©LR#/ZÅSÃ[Gjjh†©ql"¿§p’p‡C™Öf…P¨™Ûf‘¾"Nl°péÍÅ^¸ÀãF:›tØÞä#,ÍT„»‰ÁhðÑ9wå`ºwÜÚËA•¢ß2‚£ù´œ3L—[#9I1ÀíØ’Ýœ}=ˆ.Àƒ åp•Bj¬šz¸S€ÖÄröj×xWF(E!Zæ´ڇ.o. 6¥Û³#,kœð\fÑ`±„ç—x¸‡kÈDÔëi¤Y¾YÚ·¦4$ ²4(pïŠ2ªTšh"†ÚÅuu°Ä2©Í²Ð;ÆàHB,‰’&l`2&%É#,ÀäàÐ&xÉÀÕ„ *‚–BLP16ˆq›ðle %3$0 œ @A]ªƒ^]{…ˆ{gÁ¯¨‘#/ÿVdÏ’¹M8¤Qb{(=G÷+t Ãä@û¥˜}cþÎ ©>ø½ªˆ8KI®ÊvO;Ø.?ÐhîÄ™”z© KBùébìU¤½sã#/¦˜w]ÝÜ»–íôÖ¼kü[*¬›jÅ[Iµjü6¥¥£H>ïf0Áú™ƒÏçµ'w¹z—>(¸rþçÂ|Öò‡¯©ü 4µ¢—ÓŠâk|t¶u+W…þ@n.¬­…¨ê¬ÞÔrØr­$®E#,“{:iÃYÞ%lšeäʵS0:2¥KŠYk2k/y¶Òl¡´‚‡ßcR×­F(«¥(‰¡ÛÁf±‘EÓ)xšpxÖÞ6ÙGŹ›Çy& I-.é)„ Teæž]©ñ%íÓÃíÉJÅ4äD™æ\5&艹’èpŠDt7Û‡š¡vJ4c:Úo¡Æ:hÜO–yU6oÌI¤&1÷" Ú#,JwØOXéáÎ-â­6éÂQL°¬RŸ1I‹SvÌ“3#]ðç7jg=5fgIÖÛÅU#,7¾ oSi®k™É_3O¦R™Î>Ó;²cÛé Œ’d*MhÃ#,TáŽC KÊŠÖˆ{Ò©|&Å5µi‚ýŒþ,å#,©( …bˆÅ†ääcŒëVéJ°d@)‚À5˜±‚.+£d=vúFÕ.6–2*””‡I¸#/Ñ: 4,h`БKhƒPT”4 I$Y¹ YÉ.…*R«ˆD„Uüa„¬i"X/,»ïSù*£œv4,Õ#,ŠB@½T¦‘î*®Ðçl]šé±QÝÕéRµc,•2FáK èíƒ2‰­ÒÍ76èUÛWi5ƒt®ë®î)7Šå¯]®L´í<Ýw™W“bb•ºšÜ65Úh‘IY”ÿ›3"G(¦Ñ³Å{mÅ­¼le-¦U$„¤È›5±­5"™®¥®•¥”´É­,Êšª4ùµòóÂj-P`±S4Um ¬HŠ†âÞ¿#'ˆb¿LlhE¡4Ñ£à˜—`IˆPÀ€¡Q6[@‚—bQ€Q‘°X!¶+åØD<ÎÓÙ`ôå„ôŒ.‡cÓOÒ–œ1,¦a™«Úlùdú> €zBq9ÇÐQA}€Ÿ$ fX M¤Õ"h”7Lx®”ÒòÒÖá#$ÅRCGåg`“2TÔ±‡“U¦ÚN9¦*žGvtvFàè<Âõ&³#/TàŸcøX:˜·½*UR ¨”‚Yüô Z2"S ¨FV$¥×©Þ³í§‰Þžx‡8Ã%£÷hc»U‹}™9,m§é€jÒ#$AMi­K‘Ù˜ˆ<«…­L¦E| w$¤0‘ EhÒ·gêýÎíœu·kÒ<pïÖò«Ôh¹p¨îÙÓGY°üÉÌ_“-,ÎúKʨd"ä@EX—nr­ýÌ–srÆ™°- ²ód i`FÖÃÊ»¹ù¶Cd%GkÁŸ&}ŠçDîq në’r¹!œÎD¹\BÆ’¢«þ[[#,Ï[pM6ÂÔèOÆî¥ÙËB— ™É¦îä˜òH€DAˆ¤ @Wð|}_Q#/æ{³¡­¼“¿}”~¨¨gRŽ?àh`(TÛô•P 7ç™#$˜izvKQµÏî¨Õ’/aDÔ—·nª"d“xÖ×"ÊhšÉ1­æíZäÓiXÊ[I²‹HŠi–K)’•E1K-@¥ö®°¥«)˜lÚ1&ÑFÚ¦µMÓŠ6‘ª•ÝtÚ„¾®Öí^Ý»*b(2#/em¥­)­IkjhÆ¥Wî*®µó¹Ư~í’lŠ-cdµm²$‘6ËZܺÒѤʤš–ÛÏ;›i´ÙE0©«#,¶–ËI½­ª[c¨tVl·]yÜ’–ÔÉ¡®[«5I^ ¬Õâ»bS« o ®Æ+5mFHÿ|.núåêÍ9n<¯%`:1á·Œ²í+;(åxâ{ýýuèéžÑ’hgU¨*ð’Á\­v¯zª¹Myaa“6zùèú`º'„Ê]TRÖKEÑ:K@¬¶å‹ ¸C-tªŽB¤2ª#‚F `’ $€PžÝõ¹'U{­!­šVÍ6׺ڮ"£ î”ÀbBÍ%@ˆT]UBX]-¶*æƱª·}ΫW›L¦AÑQ3¦Âšl)E1R :¦ÕQdµ¥³Q³´™‰m"„£R“T¦ÛZmšfÖMl4¦ŠT¦ß¹C#/$ËQY¶% ”eiI#/46›e)¤MIš6f2ŒPXŒ4el¢›&I, “V-R•AQR›*R™*’´RU!‹$mJ%hµ›M !BJLX)2“ ¦I¦J–j¦ØƨŠ²$mE,LÚ“$‹+Z–k&MRKJm²ÊÚ’ÕkßU®íµ¥f¶›Ie©#,%½åµ®›6mjSUdµZ5^Í^löUsZõš¬[m¥-‚ÚV‘*´©VÚ5¯Ö‡_£ì+È7ºÃ}ÿ£fMͶGL’òåEÔJØõòc³'f쌴Óýõ4 €`ôš‡üS†2‰¡‹ß#,Åy—i½Á¦ÔSÇ*IRbx‡€RF½.m£œÔàœx…*P‚¥~]Å('~¬ šãŒ>‚7 B8ϾŒ5üù'àûÜ#/$S1é„ÉR‡Ûm;5Ç}à—®…]¦¥c{¶&)tÓÌ8.X9†êm‰Sõ#íô+ç/±’•n(4ªè~“.ÃBíq1Ô*LáPT_ã¨|ÛeI¡ý²=²7Þ¥|| ÏÃœáuæŒÙ‚öÞ YÎ#,Ü…$ój(°*¼n(ugK}φØõl£qGFù¬Öû ³]aPÌȵ¨|Ãu#evìX!öQ#,ÓßÖÛÛ´à"ÅH<»€#$bÛª0m¾xQ@R+¥rÐNd#/Èt(Ý“#$ž‚"2! Ö$êåKšð5ZÅsªåz±VbÂöNé}»4,ŠÀˆ.íÔy VŠ*J¡ ÜN²jçGM9:T¥5[W^• iô» è%?Zö{€@<óÓw‹Ýغú½±¼åìlyWVÎúS=¡¨4d€û8ÚÃÎuÀ“8 wüÿÌÉ`*ÍYÏ¡E#/e"ŸV.â?±¼µ)& m ,JÒþÏßkåªÖ÷+-Š1¶†VR@TbÑœÕDÐ1¬h†@‰‘„mZ#,xˆjI­ÔZáQ³IìñoMéh¼½úæy³‹Ý£C#,cŠ±¬Œ‚h¼°Š±³‡ƒݶ©g6&ؘ¡»Kq‹±Å,Teº!Œ4°ª©ét2`©jÐñH¤Â¦?Š¡HkŠFÝ´¹@„I[€ ÍÖÇ.q½J<BGàhÊQ¦ôÕhXÐôæ‚v -‡v¾”=äF”§:qHѪJÇ.2;p>0d'´‰§lzC¡R»={L²Rì}QèÒw#/äBH 7sRpäÓ·£z· ¡¨u=šd¦0-J0U¤ F$˜\/«²¶æ»R¶‹×£\åˆøòú‚â@'3¢¨ò±sný›nåõ}aÌ>Yµ–5&q?Niý->×ÝPcGâës¹$çL¼•·,ET4µæò8äÜ’°—¢v…ïP•š-Òdã©3¤)32ÀmdBÁ5érÍô’²¦TF#/߯zÁý97ƇçñzáïÞÇ„¨!Ÿj¤*ñÏX¥cçß0ÁøªÑ1ò,8™gè‚:16º0™±báX£Àúè¹´#/•ñã­tÂù_µ `à¥ó¡;P඙µœÅüó䘵 àü¾R¶+Úøsg8ÚKæxuåå4Í´mXÒLh 4Ô¤¤ñhòÔEd47 ¨ F2e4{&pp}lìqS¯=;+R¹ŒÎP"Ü 6¹dl¢ö#;§€õ‹]·Œy˜¢ Óm§…yzbzÊÁÌ:%ÑhÔ™8f^!˜, Øj"jÖ½+%šéZMûé:Ÿeûà‚ª‡§ û(•T½YB @œžY•qZò‘ïµ¾Õ3í x‰€Ð ’ ƒd -ê¡V)ÂQ48é1D=h «@ÒdPA È…¶»g«H†}·½äq%”@WS^#,†òd¿î4+ ðÈRÀ!€²ŒŠx£"TL$zÑa\ÕÄ McõøÂs‹IàrÂÕùïÎ3"1¢wSsDÁ¶×M„NÑ"I †Ï~^šØ;Š/ÏÅkÀ9!µ¸)5¸8–4Ò‹Ž#LFœ;"ešÝ´6ÄÎ6$L9°pK4#$1ÌÈwó •XŠ¾”R¯Oaz‹#$ñ=;NÝÖo+fy*wЙ¹çF|û Å"TX¥BR1š,!E@«Þo´³Ñ×E1&Œµ€Æ$‹,!IŠâã”È#N•Ú\/èÃü#$]» : ¸G[ÈØR#$œ£¦H…’4Šœ PEw`X¨2#/HÃ*¨ÈÆâÑ\ˆ^Èõ®ïƒŠœ¸ö´á—®ìg8ØHÆ›VBI‰­6‡¬;©¿§CgEñ®Bø÷ €WÅŽ¥ö÷Â^-h”‘SJ§]I³0"Æ#/Íè©tJŽÎøy®õÝÝt¼îÂ2žv¹ÍÄÀŽ+µ¹,Òçžu ñ¦éØ#I^Ùã'Ó~‡-F’ àEHvjDÕ|2Ú½‚=–Ù#,½2ã».ªÓ`:·°™l QQ׶^¤#/µâ[…â±j˜¦«XY!Æbq!gù~ße>“@ßJ8&ýþYtªïˆzo9z±<âWsÔ)±PN­í;1‡ zðDÞlÃ(ÇÇ-™& `ŒRA„ôì2Øé*ZüúZI¬€ªLÕ0U‘‡Ûù`Ðrw0K:|}Q#/F÷,0%à'—Š`™{.¶Ø‹Z^ºÕéËË—xº“o­»"fbBw¯+Ö«Ö®’Q›¶¶Žªø]¶½"تמ§‚3Û¼¥ã§vâ™*åÌRöJ^dCV(ÅiH@M6í××;ÒÚD9Š;b¾ÂêmîÓ5×›Êd>^Κp#$F ãÕÞ!¨ÕrO§wó’eJÖ‡3„1}ç}î¦Rg¿s%_–^—5øYÍš-¿uÓä¹||¯Jð~‡|:´jɵVFaþ´`¬*™23a¹$ž*+{ªi£h™Ej¹FU4Òi©]t\ۡɉ,ŠÅ´j¿mÌbÄVŠ×Æ”U^—¥êmkÆåYfß¿ýñ¶É¶´Û+V½*ÝrttŠ7ĸeÀ ®h 'kåŠг)ðÆ–.»YœHe´"„¶JJˆPÉB7&®r°„2ý-„Øo!%#$8w,´„HÂù-ሪÃ0 ¡‚±Å!ªÂ7DÀšÛ—§#Wg8hj„önI` læÓ3s®õÁ=²QPÑEÿ8GBÒ”NÄÝœ´¦#$m°©ùU*ŒµVzPT*éd“W˜fTp9°Ë zœ :µ8}ÞŠ1CøvT*5¨¤H•E,‹2*4›EQ©Û[nª×Í_OÓ›^âldˆÊê²àÌi“8²Èà¹{ªë~]°±[TyÅP"¡iÄ1²ƒoE½óãÁõ†çq8`ZÑAœõ²#,Æ¡@ ˆ(À°,ä]ÎàÒ¯—P†¬3Ëßû°ÀEØçP\ ‘m € 9{>¼0PhÅ#/€‚Qþˆš×aÅ\M¾W>»õnlçpñTe†áà(‹#$"BDGåÄ4÷ëÕI#,`—ÄÑÃùñ>Ä~]ûÏÛýÙ¸üE÷ÜäÏcK»>[^E¬n»&ß­¡=Ň wuŒðºy‚¼U¡Í?—ÞG0P­ñÇø"$„<ïã¬Ë‹ÛÕ#,öúuÃ1®ýŠ´ÎXýÞÝÃxsÄ„#ñ ʽÌÖ[¡MQMˆ> r;•ú=˜EþsµpëôyTI$@S°€)*”¨Š…Uda¢¥A#$dP!’;‘±f…â•‘ ‚È."+Lf¸aî¾’'v5™—îCæãqƒ2WF#/Ŧ’Å‚œ £d/Ç=bèp#,=Ç4æ|ì|Þµ?»`ñÖ¬²}cÉ ÄØžiìJ3:àï4G…œJÇúAÝÈ8É$ $ê % v_‰l‡q„}ì–©-%"¸iyHvý}‰óÌ.ñJ£Ÿ—³Ï—K©A…\:“?1Ô€g’ó>'¤ÅuØ{jHÝfï)@PvA›Kòf ”ÔT„5Âã§u”ûÔ‰ÚE@ëÄ„‘˜sô|y OÆ$¬… u¤7©ôµ¦Öæi þÂý®¨hÃ5P**…Q3ü·n)¢‰– ^J¤…2–#$’Çv#h#/ì þL hþö^ª©uª°¥I#/muX©"à.º…Uã–w}r$´ÆÛM’¹Û:g:F0¶ 0#BÌ £&D®’f²Úâo*QMQošR\!„$Z*SS ØÄ[U›Ê#,1´61™Y+B)„ÔÆ6«]ZŒ`”im{®U»ãÚ¹Z1mìÚèïj#/³–”y1†&&ùe5k¤Hƃ{µÍ´[pƽ›Æɵx±·¿®B1ŒŒŒç+–=´!`Ä3†VM¨“F`L%¥¬ÊYl€êoeæ—5t¹p` T©hZCd-…Ô\Ô=eXwY m£®C7U¶66›¯'wNíËbæÚ6•Ý+–æØ®[—Á¼bLk×w¥Æ‡—I³aH‰/Y5M¦hÐÞ¨š¦tëÆc „ŒêEÛûõ˜i–4ºµ&¬ÍÔF±BáåB¸Ô›:¢£’Ëbn@ 8ZÖÔ¬¬;µMSÇ+Cclâ$(ÐÆ$QâÖó<7Ö‡õ}‡˜†l'DÈŒ‚Ž?y²‡Ä¦–Úäò©0¹šjO#,î¢>o„‡…PÂ3åÕ3)ª“Yã¶Úï;uäËPÄ h`'ÃñÃ÷ÒSÇIúÃ)Ä°ìDЊ"±„HA¤¯qÞ}¯_"Àh~¨*D<%œ;þ^žï m=c©¢Æן ÍqC3Ñ a#$¨RAVŠ(F¥Wø"¡XÄ—åBª&Â1‹ÆPà‹#/¥ó(7]u|µ¸ÌBS™íO'6ÑÇ&@𛟶8Á¼oUQ E_…V4x¼·/ŠóK&ÖKy×S*YUÍs[ů¸«yeéÑ[%k#,ªŽšÅŠê»ª-zjö»(˜¢THS#$Ý„. °.U¢ÌL)%µ&­Išl™­Àm°#,4õ#$#/¢‰¨DdyÇE©Xýº!ÔÑï"ÖÖ 2Šö(¹j²)®\+ñHÊ¢—€>s0¡†"HÂe†`ØÉ–@2…‰9$²"ב *«È¹¸ì‘À4D l©ô?zaƒL-Úó®Å~/}ÈmXp[‘,'±}²@A’%Ç»«#Ǿ’¡ä#,í0‰”£è8!DW‚bUTŠUðÏŸ•Â\6¤FÊ;*„â4\T-°¸“YÇn9 .A.Xr,±á•sO®/H)QPÏè ,®‹øÄùñ‰¹Àjæ#Ô#$•Cg›Qu؈x¡hØ:Êï –•()j¤ (Ò–”©ªÆÔ3i¯y]±¦«4ÖSÔ®£h#0Pˆ"(’TBþ˜:'3 r<û=–ˆF«²dom¹¾æ©@¢‚åYȈ^ã(ÑÀ‘@:4B © ãܼú ”kx”`ÅJæͧ};­#ìaƒ$9ñÓªLM&M´P‚©‹‡ýo#,ËÌg8¨¼±†bCÖ°¡ é:q˜j5,ê’bcC&™[E µ¬pc#,°vº¨ ÄÓÃܘ‘”}†#$Œ(r¶ˆ7Û‚ Tж/¥-ÞÑðOCÕÛXD’I"BLÁçP'ÎQ Ò8ᛕ¸Ê>§OÔ¡ HT {Çî=’i_ŒŒŠ0”ÔÑ$PÝ0ÂÔZi´Cÿ¿`ˆlÐÙ$sÐÜ@£ïf{Σ¤«“g4Ä~Ë#/(jct3$ÇÇ´€éÒék’#$Cø1Jt³ff¸#’î:I†0(€«³ãW2Œâg!’T"‚ (@Û!).TΖ*B5MÈ >É®û绉œóÈpC'ØF-†èÁÑϪƒ®ÉÍ¿Òˆ€?Ë‹‘ÊÄ4ÏáýY˜I2r*­Éˆs‰s£/i‘ÃL³=…Xʤúá£'N‚}I樗ؚfߨÅCðûƒw¬ ¦uø̺@X)"¢›l ÂÔ”™,Ó1­Mm-I±­ÊkðÊè‚M*e¥Ÿ¥«rÚ™š¦È´P³+$­”U1,[eU+M¬Ó-f[e‰-bÒˆªmLÄÙªÍMSlVÛÀF–ƒ6¢ÌP4?;J?aûÚ>¦ÉÃmÃ\¶¤"f"à#ŠƒÒ)¿õ¥€5$n§5µFµ‹]M«\ÖìÞ#,¼Â£_ÇÚkÓjýÍ奧թ®±èwuoÌx#$(ר…JŒ‚5 ±=H$Èâ±û“‹ ûLP<¢¾­”‘q*‰2¥E±TwĤ,øÊ0}¸ÁAÔ“(¡ûºlH.{K¶Š^$(Ϙ‚ø#/z<ûøŒ8D (ŠTUöDá ÏZqCX~¶+‰ì°‚a!#$¢/H #/•¢þh·" {RÝ }*zО!{9^ű”xŽãá¿<³ØmÙsVƒ #$…Õ\’CB>³¿Ê¥§m©#,±¸¶^ÐŒ"¹é#/oæ=EÌfw¬ŒŒótqü¥Å\/ÁK 2ê¹­çÆö÷ú•MäNÐ(iâzI‹$^#/ôN±¢p#,§+U­kHEÊ%ÍÞl0wŠÁéÖ¡“¸ƒr 5›ƒwyc(;0Måá€Rxó£$ækAB#/PPµÄûv§ò¹º+Æ"µŒ!¨ŠÐÐÑ$p¬I—õ;j8J¢Š,ÜXš‹•;ÝçåØrløÅ(õ¡÷~%Ô>èceïÓ £KFÈü2ôS^º¯F…4}¦[Q°š{p‚w:_ñq†¸8tÖ^0]Àé®×_âätb¤a {þÝxqÏ·ó?RóiæÑ!!ï#$å5›ò6·Ô,ä¯LéúÈr`O›ëë@RMR#N#/²ƒ))e% h0@P0|~¯LuÚµ/̾Uç+ÑË+ÊŒ$Ú=L†&ð£û7­`Åû{ÓˆvÒÞ„™'·ûæ&ѬHU¦BÊ0G%²‚³ÕVi£L®mà ê¤pÕýÿ&XéËÏUÈ·Éljè@‚Y•Tñ0X#$I#$ l@&(@hdEiR´@âŠY,Š"m0À#/ÜþÒƒÃJdöÌÑ×»Ó:¾JŠñw6ÐøvÿÇ¡Ž¼¨Çׇ³M™;ÎGØ6èÄCw3N¯QˆqŠ© !‚”s«z) â=~'!¹eV[¤Z#$ôá‹#,ã¯Ý@jêêôìCM›ŽÜò&›Aë:ÃíÊ&²"úŸw¥ÓTËô*z¼%0<ˆ$äÁ@¦«×Uè¦ dKiyÛšåyçF‹Y#/´¥(d„Š0Š B*ŒL®ŒBHTˆƒ*‰F2Á >§¡ÐØQAl Gû(]›kRAÝÄAPGpa<I °û-³øúÖ"¨È##$¬K²"­™m ¡†a€Fµ"h}3ÖZýaM»½·®²±»¢ái— Ʊª4 õˆ#0©•2´ p™,¶ P“TÀUi–€‰‡(#,ie³5YB-°eSh²- èA’‚„KI{Ù6Ä&‘6pæQ5ªbÀ¯P#X¡²ed9q¶žB[ºaÑà›È”fÙ#,DˆHFÌ—#$ÂL&‘›øÛD#$é„‚J¯ è;â[‰E7rlŽ!0u%ƒɲوà##,%Ü#/3Ú¾¸ þ§;#/eâh’õd #/X@$Gä•1—%<9z;g`PlÂ}>šZ\å[½Þ¿P½’ é¨j#$J Xü ´U|XC)DɔĮŽÒNhë¡(Cªì-¯Æ­¿]µæVi,¨ÖJØ™hÙ-&­Rš×ãUêÉbT#$}öÙlX[$¤)#/`É"gjw$çÜ1ù0çW,%6tmSÒ6"¨«>ËY«!P÷͉Jpèqá¸ë3÷cW §Æ5ëŸAG[GÅP¾— yˆ`‡C¶ÏzO„ÝGžq#/¼óþõ¶õW›mœ*¿à¿%‘m—›Ý>“Ák}LÖãi„“dÙTA¿7”Ê#,ßñëǤ{×Øx­Úò}h`° ¢jš‚Ð7ªˆ ™#ÃÃ0뚆q|L=ž“$F*1‹mŒO§NAÌbÆ,QžŠÍæðì&Ù3‘°kŒÕ&˜†72^A#$ •·4ßµçC0[E2Ñ,Í)¨'´ø)|eÞßVØ·>fÒ öøÇc}íºþ‚7;QÀç¯rZ®Ã'H»ykh1&z>É{áOìôkëÇ‹DC߯µÙtf(5ô;¼}‡€¦­H‘à*·Œáp5ì=}¿eÃÛ„#/Nà ¨=âaÆ2®ØÀ‹r¯1)¸¹Ðþšlfoà|žÄÆ™×j]ÚN±œé­^y#‰Õe‡X¦´3oaáóbm>ª$ò2™íî/xs…F åÃíß/¦×}ÆÎOr—»S¢Píò6d†jØŽ¨S̓#/T¨OÒ—µ ¹Â‡#,¸ûŸ˜¼:æ>Káшð–àF1‡ÁÌ"î#$¦H Wv¡‚Š©†ILFBøä¹3TKEXT",!/ÞRÐ@à†0ÙìÒ÷èQ…¹íÑD#,¡[¼ØÍAú„…ÇýßÀ¿\ÉuAb ,Qà-¶‹‹„dÉ(ËQbH;¥(×VyÛ¹ÖîuÞªjÛ¤ˆÓĈˆŸ#/ÂààD!š#'‹v®#,¦_¹Òæz"N÷ê=¿zEë<×^…I&þõð1û›„$Õ¥µ­[›õ‚ûv§Ã$Š|vëãÇÙ›åys‘éS³Ê!¯Ú>m#,:4ÝÑ Ù†¬Ya!pÜ tRyjÑú(=¤¸ :àj•C…4tiÂ7qr<„–«b/ÀV‘àÛ,%§³°eûôl]™dÖlΗM²–@•AYÒû ©Ð­ëýµ§Ú#£+ŒFµ43„š†@èÂ4jÃaèä;ƒVu1"–BËB30Ã-˜WéÚ¡; €å1ÖïãmÄÙ‘F&ÌÄÆý¨mƒgV÷¼Ú.,¬P= Ä#,ç®n÷Wa³Pø#$ŒARy6#éoèõ!cìwœ}Z‚Þ:¥|9ú.``}j.ûz:棰|é8½m¿¬kéÊÿÃ]b0Va¨)S}¢#Õ®6—1ÒVøL#òkcë8:Ø×SÖQ™0~¸}³÷?÷þjB…,NuF»/µ™}3ÓÅt\n6…îb>ÿtEGt…ÎúLIbœ”UÖؘ^2#/ü#,eíh«Õ¶fa­}÷CÖ¡p…y#o&ƒ`#,B#/b|ôì\@8”Ãz‹â ¯†'xmo#/tCì|׉‹CiƒÖ°} 7´Pˆ“½£Ÿƒã’óÚ÷.ŒYÐìˆàÜfì@Þ@=ÞR¾°Èçn)ëÖk´€eª ¼<÷º°$’t"L"Œbà(ˆkeÝœ·Êüj#,rDL\&23uA¦—ëÅ0"ÐzB˜ßV#$ö„Ъö@æUƒžo4Úl^ÛCxþLFx„ܽ:B…ºM!p<Ë¡1ØJL#/3à(½ò©$r­êÆX1ç’âß౹ߜ]ôDI"ÀxºŒ¸;%?ËX,)º³é]†ý1A¸ÈäŠd’fá¾A1û²Úc”3…¡±ŸÑ[5hñ½JèXÈhãö>ìi é±,#rL‚ ÍRþz¾½Ž¬} AúÈ0Œ ¯TJóª„!‹Äå\C#Ê™šATÃN½—A9ÄJ‡µ\Úé÷Û¢ÕŠÔ[k¨Ú-¶Æ²cTšÑ¬–6±[WŠ¶æØÛ\EMl1…Èë42]ÿ;t½ÊçQ¤¹–¤¤b 4È#, Fd*ØVØÅñëØo:6ÝvýØ3€›H7,àw>¢Å7NÚö˜ŠbŠMJÏ=¸}‡ 6eöѯŽ¶uýS×í¸Aö©ˆ]5t<CQ„Ûdƒ"å›a¨Ñ4Æd0&3¿bò(‡ãØžã¨C9¬í~`E hy+å³ ò#,†¸!"!w v0aæ“Ò;ì‹ÕëÔ}AíÊçðûðæɇ_¨@Û&Ïðvl¢p`vã‹œÄà¶@;$™È8åß®Š_2CÐF©CÓCÙ[ŠŠ|C0Áýa#,¶Ú³ͪBfC:ˆáÈ¥¡5MR¶iE¿ßµë®˜% ƒgRHB¶oÌÞy(0ï ÿ£eõ:™™®…#/‰¶ X#,W9*ªJ Æ>2GǾ¯^Låw"ô×Z£z”“d™Iht@=Él…¦°@Õëb…1¸¾•Ž«„DŠèäHÙB(¥R#/ÐQ¬­f  ÈHáøóÕk×38é ²ª pÄ7†$d‚2ªA4Uj…@qÙŸ£êõ»êe>{}ýO뱎kÀÃÖ&‘„ŽBTÁ6PbÄd&©¡=©ì¯vq‚ùb!”¼&…CŸ¸÷Ù]•2K#¸°å}†¦6©ažÜ­òVÄǤõ£†Ž°Ìð(uUEB…mÊ=·e×àšŽûY ßý#,»5ÑaAUG<´™eÓeôŸÛm:W^£Ãåíåð ßX÷¡x¦ÍüŒ!DõѺýZË©ËÌñ›V‡ËS?…RÝz%²]PªŠÍ4£T#,u¬³FB™#/dª¡bÁ#$‡Þ›´›%'½Í<àcÚîBIàÔLlaAÂ*šŠŠIÁA¦HM)S35Š†‹Fºë¨Å#$èKóñâ#,ÐYQ›Ã¹ 1f…JÆ1¦“Œ†‡E­AÔ¡C C#Áš¶Ž=T¨Ä8:5£*`¨Â$HrEÓ,‚>pƒHhLímoÙ¸!dô&~©l5Ú¿wÏ…yvîÈI¬Z¬¦ºUÍóÍÌ‹6J´•s¤‘žn»I•!J-+¾<ždõ6ï^¼Q+1§­ÖìÐyuÔ½º×•I­DV„Ó›cYebÐË1ªQ^šóÆ®´Ù©”#$¨5+e+42˜ØÅ©$‹)´ØÉfÙ™&FÛ)izîÞ]W&ܹ·$nºå·4í×´¹¯7äM*Z†D¤œ1YrÆEb0c[0¥”ºTÒ^`\QB$@«ºc!Ð4´ÖÌ“¬ƒV­Fˆ Àn»'§7XDVÙF庬ÍKb‹LL6û*­c  o#ⶉ>\x4ž{*8É´ÚP nÜk†aŠ»`»à ²Ì1i¡K0K•(HV½mt¢Œ|;•š“ÃôxãÕ4¨«m¦ë¶jB[s¤Ë‘ìÚñE^̳#½¼×µ°Úá£! fÌ´ŒB‘¶›hÙÂ$©Vex¬ˆ¬(ÚLCFãÚXÉf6ZIYZôA ±¬%F³¢")"ÝT‚&0ÝÜF¿V\ã„F£ o C+vHÝ— ̃MN q›T7v:ãÊV¥„&&‚±9—óÕkckR"úšOå`i’l(A££ÃÍÄ£ÞÂ&ìÛÒ™#$Ï*M\2h}ÉêÕÜô@qž-©šSJ^PÙ<¨GÚ.ÃN'ÊIJG†¬ÜÚÚ0qÂÙÖ‘¥Ã#$Õ4‹†À5˜Å¶c{zª J¦Ï B– À¡‘#é5Îô$Ž#,Ú8Úöž¦e™þFŒ%9¸i‡ tÌÜɬð€ Ø|»MK_]b&È¢Þ×#,lÙ[íE»!6Ú±~.Žžl¶Ç\šàRa–&q[!]2ôb²ö³F5ô®4°xщ‚Z­%Sm•›âiu©¾8ÍBi)ÄãY!¡&s•Z„Z6ma¥CWªŽXv‚9jz1f†F [†â#ÏÝáòš‚ýÏ€U¡‚¨%H?ŽD€ÄâíL:-16Q'*Vác(3*­Ûß››ôJ>úyÃ#,!M %(Š ÑiD@„ÒÛ*Ò#,iR*#, H˜ƒØè0c¤(ŠBb¨cI‹\£H„$—›þÖÄG=çN£ÒQöj#,bÞº>ïÏK2Î):'uù©±Z\]@+UT9†>X±Ù2š?)(ÄHægÉo6ÍyÏOFñ>§~‡o‹øÎ6’·í}w<]SlŽˆ¶&¤OâúyCɽb¹êšÑŠFg©´ÛÃ×»©’–Fö÷t‹—¡ÊótÕà{4óz¹¬š¸Ùs«"–U™káä”ááç×CÓC¿m«c4¶ýfîň„’·33nN£fó¢ºç3naÙÆwhá¡A£±­Ö¾f¯#,¨°*°ƒ&cŽv hîÆU6–dI#/ê»–åçC‚÷®iðyng~þóCoÏQtPh£]¶°a&òù¾ƒ,h#/?˜rtDÉÄÜ.Qå7Žö£÷õgg^i¹åÈ»tÚƒSKM³jºæ­úì䇜ôMÇi§#$c®”BŽ†ÿ_¯†hžî&w†c™N™ûûew¿‡åáo!³b#.÷jkÖÍRØ™×#,CŠS)ÕüB0ù|¿;Ÿ6\|Ðà>`io ‘Y!#$ :¼FE˜…°´%Ôl–#$úàHš6Æ‘@²ŽØ˜ˆY&TÔªQÈÙ¤4;U\#,ªÀ»6·#,­Ój’ÕÞ:,U‹^u˦®ÖÜÛ»s!Ë«ÆÔSÃ,–-"Ò1R¥\㺮îÕ‹Rm–¦¾*«Æ·’¶“t«vÝyæñŠÅmâÚ*½óKhIBÍ#,/É‹hXŽiBšª•Vê»Y×]ÊÂôâªZ(…”¢…DŒ!B4ÅV k*Ï9"0…ÕÀ IÒ2äMˆP¢V¢£L!PÌ…Œ`¢H†ˆ@¸]ø¼·Ó(k H%I(†X@QQj”¦©ùŽª)²‹X¬ÄÍ4¨¶*Š™ŠE¨¶6³+Ó5I²Y”LɉTÑDmLɲlklÕçjº3²”#/"*@æ}¾’ã¡ }ÿ„bù궼õ“j¡*DI,¿ž»ý³íð¿o“Íà·«ú=w.g6ÎÒÁêMÍÑÏ+«»äÈ(r/óQÔï$ ,V·âjiµ¤¦Vö9¾êêhÕGìÍo±ZÜ-«Å®Ÿ·ÕÔ3ÍÝDm§wg]k»IK[sm£ImÍr泫´¥kJÖW®ÝšÍE )H´Ñò³þ¹ ‡fàFè£ÂHûá@Ì4æ&‰ ˆ$AT C™±p&òqÌ–ª€¤!ØdƒFæ¨XCa×Ëx[D¡(6Îa Áy$„50^5+´¹†)ÂKÙøÔû®Ô÷Ž§Ëƒ^‰¯Â,ñÀ±ªLaƒ>5ÙE0.`*ëD†TE„úf›#$‡ÞxÀÙ°ú$OùëÄ͸Á½ªfc1¹ó²ÁÆÆ1•ÜÉ4Ô&1€¦ ÚšnŽ 4Ã2Gœ;“o£´Êq)mwŒ„¤yú·˜óïÚ´! 6ÚxLl)¢ ˜¬6|U¿¬¼9Ž0NëP ÖÈs'ÞWIv6_7{Æñ£ÂhSK͆dÄ—‘<Èãg|–Ô¡àø¡E]Ûì®xÎMð²ÛhítKEHæ¦X^¸Áƒ† ¥“#,1.ïg¹àš,Ÿ’ñ¢HÆ ‹Ö;¢ä¹Ã…øèVî™×•Àì@Q6©³8Ùlý8Ú~ßòÖ<0TLU‹}&e”ꕵR±CÖI°ú›QG’1 ¯¬3 ‘7Á>ˆˆÂ+ ¥hÕ%·Ê—ÞV®š“Mòq½#/¸ÆEFÄÊ#/6!/($Xˆ‹$)#$……ËÝyÈ#,qòÅ\¬ÿw†ì;¹QqŸM H#/ D _¦>â: ÷&/êq‰!@¡$Du×iíÅ‹[›UÓjñ¯%ªN®RX3#(a(I”Æ•"“"ʪ™ †¦b`'âÀH¹·’+lÉ1“mjæšÅñöÉUçu\Dö]â®Ò"6—5ååE=ÉS„«IÈDNµ›¸V<Ócµ²3(i˜6ÐKhÛ5jRƒB­´ Õ…ZdHTlm L(Q"$ªˆP¨P¬V1`4¼TrÀLÄ+²¬?t#&’`RàYP3.l°Nðù[+¸Å$SLb ‚ƒRYR@3Éý½þ|ï9P½u¸ÆÇëÙôFX}çá†{‘Õ8|Ô>'pív¹×:íå#'\IË—“î3&ðI£Ç< j6lÏÛ»-¹ s;9`S‰@$×ÛxLD«zµ~½^­k{‘Ú`xg—Ö|@æC鶌­F'áŸ÷~ö¥èa!ºÄš¦Íõˆq8PýŸÜßsÁkùZ#,ô„Œdù,dâžö?FM8ÍCõ¸#$Í¡qΆp|å¡Q< ‹CàêuHÐ]#,Ðô2îË—Œ€ TY¶ûÙÑô#/¡lxÅWŸMgKãf@_(¦™#,Á@7´"¢IheŠ'™­šh€A6õ#,‰œÏ+„½1ñQ‡ÍªÁ™cBbÕ[Ã’ƒk8( DRª%+H£Ûh#$)`®;Y@É"☮-ƒÁã÷ª%âýÁuAÁȯFœgdï‡_»¨$±-ñ¬Žî'¶©õ>ê›&áò‡6»#m›Õ£#$3âU:sˆÎNô©êEýOè>¹ÀÞlMõÊ »sUt¢Uݬ·ES#æ”1« gü—úJ¨µq;S ¸#,Ÿ ŽáC\¼„¦€ª¤¤VHF)€”ÆO`Y°ŽãñÖ¾¨É±´¯^ùçžiÞwYrÕÃJ:îñy#,‰Nneæãi²ÈšI ²¥¨ñ¶í6É¢Å%&Ɔƒ snW6ÜÝÇtÞo.Üu×lÇ:+»·H®^-ãɶ9M–òy-Õ˹¬Ë»ËTÛQ#ÎÛk›–ºj²[F¥,m:ܦ̲lšÏ;º7NZîÌé®H¥NíÐr®²çY¨´hå JB+P$Fˆ+GùlØEv·K"ëOTÃpŽ¸:Ñ"#/õìôî°:ÏLÄ<`8#$v£ý}¡Ý Áƒ¨B‚R ŒD°¶ »þÀOE7'<”Ãß©´m#/nY)#,PQÖ#/Âf›´•¬„ˆÒÕ tn–±Ÿ¢l>¤#,`ÿ–¾è< ÂH œU:¶Á¢¢²¨#$€EQ‰‰Pª*œBŸž)¯u±W×f•×«NÙ«rÀYƒdj TNp,êbF"´0ŒÌ¹ÑwÏ\#,¡’y'7 $d=EOêDÚñç§í[Ýa3F×T5e–‘&¢Ú—IÆ,4øJ¾¦\C‘Æ}C²^šõµ.v¹’µ5Æ1âì¡,™&8(BIa]f<™·d„T®„wø±ÐÈmšZ*ÐÎNýœw|»ÉÁÊ5P«/*­¶Â½Úa_?°îq^.úZ³ÁšáO˜Dïh9àTø³뎴n¯„¨ƒ²~UAœuœ·‰´Gø",ˆ€Iꡦ#/«\©áj"ÐD뙬â\Λ[÷@-ö#/o g üÞ¿ÖõÉÇ~^P?ÕÏõAÐóž0ýÀ‚#Ši LѧéÖ¿ŠÖÙ>æüI$#$t> *hÆêßÊBxÏ–=%¬X¿¸¯ÕöV)Ñu©A_´d EQ²{xKÜáûrY…op–V]½Lw0Á¯‹(hgEÏËW£ p ´†‰PEG¶Å´2ÝÖŸèg4ÆÞôÄ£Rø®¦’ÓF»Å¶íÈ„ê8i’nDóÈîhXª‡&“£»6.+„Í‘Ï‹ Ù#4 üøÒON'è8"#,$´xĈ†AdÃ6ŒH–±ñÈǽ;ÐCi»kb‰Û‡(‡æû–Þ¬‹îbÛ²JC”DÌíÛ°Y"ÜP©¤œ©æ 4pQÌ®®^'b¶Æ=ŒoiËs EQƒì’a}ݑªžvsFÙ“eÕ“¾·Lc?tíÄ[šþkö4ipË,Ú¶á+hBÞãœcCÔ¿Ñ4}ÞLé9tE5&›å1œêë+Ï+Ós>Y !#—V‘ãÆ1’@òx€`؃z†'¥„Z3xŒm-1è“I£4»dîÈdY9¤™ñ—Ï&·=»!ÒFv›â"GD!A&ÑœãQl ™­¢æ öžZv³¥<Òöþg­'›#$·’¾'R¸– yG±&èÞÙƒêìÖ‚QŸ‹'nE«ÛËŒûm°S”#,ÀÓ5ÓxßÇY]HxÝë0›´¼²‹÷ý*&¯ âÁ¥¥Õ˜Z›Ä†í¾œ†cAÑ)N)ˆAoëD1œ!³ÍB)ˆ¨¦ïûìƒY#¼äõ¿µ]2¹"8n°­ˆbF#,¡âT©%J4‰tÕM#‘Æ$Xˆ’ÙˆÞHèÁ\ºYAUé{Ä}4wÀ½¤ÁU±Ò¹t#$³2ªƒˆwtêé³<€•?„³Ê]H\³Ì®¼›â_€×qÁ{øÓ$5À=|Ä@hì1+Ö!"0/†óI†½ ™ „h|ƒ¶Ìðà£{l‘X1õÎ¥FÑãÙS¸£qÑKP*Hˆd:ÎE¼ùvâ&Á3ƒdÈÕµdáwsDB„¡ÿ‚•R³ëaàêÁYš¡ÒÍ|+Q•UjUUg§ËÖ±3A¡÷ %$úÛbá$#/V !,HŒ’"SšðÉq’©SV­/½­]âÊýž‚Õ=·!{ñ4ݘT¶Ö•ô›•ãÕgEnñ Ô"ñvð©a0ëÈp˜óÇ¡ªNÚMwG"Û]#$É;UJ‹Ú5ÇO+Ř+a"Sñ·³Tg!€yÄ%@ðAKÚ”‘:Ë´#,X¦"›.[ó×ë™ÖÆGÍÜ´Ï\Õd¸@°ò#—ôS⛄ÒÝÓ>Àüb|)J6P'srFçË›6Ò±­TeBŒ'KóÛ¼tN*¨LÉÀîÏmÊ tþ#/¬ÉŒÈëïØÖ‘“¾*”-5<¡Xä1Šèô>­ æŠUwžÎ~Þ¸áë׈*hú@6å†ÁRŠMî#,(Bf Ý—8ð¾€kíá`ès9˜úÿŸßøæ„×Sç(n#,ïÄ.Á‰‘~’+x#$I ¡Ü§zCâP_᤭ûöÙo[ðËZ´Z&¶4Û(ví/WAÖ©ïÝǤzë¸ûkÌóLFdm "›Ñ6u›ØÇ{ÇY¼>g¹;%Äé<ͬ4 o˜–é‘mÀ‚9ž“§pâŽïŽàêØ€Ð,{çÐ퇋„û+læx€f#,qeÝͱ&C“&ŒYôMDW‘@¤‰¹#,±<•&=T¨s^TI $ƒž{÷¸räo8BeÙÅ_*<¶T^Tzìšzyq· ZQòâvNGk/¬Y©Ãa>ðQL #$°@€1#/F#wð4†u»ÂÛ ìÜ㨓QÔ :~·¸ÑÜ#/^¤”´!` c„€âW8µ¯³ŸõŸ×ífVREë§î)¤‘´ÚÊÛLíR‰È}Û5ø*€4ƒU 9È@,¡ ðti¼÷P˜.¨‡xÄãüG%lo#/tâæ’ü£Ý3?j†™ÚKTçkéÔúÜf†5ï"Š ýÕÎlàd]P6мÒY-è´Ü/¯‚þw‹®·L­3/H_\| 0ƒ1µý·å>ÞU«È‡ûýÕÐÚµ•ìZA+š_ûz^¹ ¹;}Û¥ÎtkmEVVw—#/P5ö2ìCuÁ”±`î+¸qŒe]°§¿ ^ŒBk‚#/AøÛþ/–Ê؆ƒ–hÛ»0«ÇÄ÷ÄþŒ¼oíó†BBFÁþ×#/¬U1ȹI#™øåÖ%1¼W†ãy\á.\i¡ ƒ§Në<Ú<î¾ÿ’Īì[þhŽÅ $œù¯-é·Ë¹gÉtÉÁªÓ½wh›HD"$ʆ„8cÝ€xî£HçB‰ÖÔ­±#, lé‡ë¨HÆ6~¼º$g#,Ù}ï•ö"£\D—´÷o~3HMØm®iäæ9\«º]®ÕI£X‹m–Ífš¥›D´•ª`‘@‹:öë°»^5¢I mC’ä²M=—6ûüOÉ#tQ=”CÖ¥Z#$°EWêý¿£zõ'êý¯26ŒÊ3dˆÑ˜ 4PM6‰DÔE&!&4J1¥*FM‰¡HI³dØ¢,b¤?ŠN\_vxÀ!ø²lÉà*΂>äÍ÷&ÛÛ}n¼ÏÓ¤“fݳ(71Œ6#,‡)°á¦5œ,k7ŽyPÒÊ€ø&ø˜·éW1Ëë?1ŽoB˜G^#,4ò`¥·mŸ@™@¨…{jE#R«5sQƒí«!êï1½Q†LˆBV̆¡‰¶ïœLÆô¸_£#,€¶ºi5U9|ÝQIé¹>Ðc°™&AïÔ8îbjMw¤êªdÓÒ„@Ç"é£2÷^ƱÇ`ûO¿×¬3tg-Ç#Kó¯ã c_{Î!§¬5H6›|)­¬xÕ$‹ù¡&_ìÿ[;çQöÎ2¤Ó|Ú#$Œ'íD E¬¶%S)JÛM8ÒŽ#$`šƒ‘RZŒbëd-Å…7QUË;®JnVÝ®ésuv¨1¹¢Ê6ÒM FÇ#,V1¬râ!…m˜Ø›hÆ@ì’1 Aš€H/+lJT!v…%¶Le…2ÂÅ›Õ+Q·×WŠ²H‚H ˆB#2¯p*åÒåÖå[mÚõËŒöÃ[s¡µàÌ e¦"û]@¦-“f@©öp É¢.£x*U,‰øµS+.¤&‹™¦ˆ¿ÍL+ö?izœ,›G.šÀè†c*d¨äC<§'¢5R_ÈuÆ׆ôR¸£ £©‚À«WE nT:)ÅšÌPy²¬`½-ppl¨¶n8$F„ÚEh$#yW!fjƒ)WMSEEm•%#ÈEZ¥·’DH”e=TlFah’iB0‡ô’šhU´T#,¦Ç‰¨’ÆYm©¦ÔÛ‰¦c"Í)¦65‰¸IƒMX•#,‰ènJEª‰×*­:R\£³Û+­µ€ PÛ«‹Bu…®©nA#/…p¬¶ŒiÖÐÙZl¥#,•-æ”aª˜ðo#/¬TÔ#,#,ƒ#$¡Í\Ľ‚S¥0éî%H%*Åp]ƒÔUÍÕ\’íj @†•  @ô®e­1xf“dǘE2VÕÙ#,œ‚¢0ÁÅÇ7âC±s”¥`«NÈÕh2È’Ga%•cQ¨œúfÍ=,$‚íðå]¾:5<öÚÌYädÆ#,®¬VÄŸXZà:âˆÑ#,5M2:Y‹"‘ƒQdñ¸3Lp„³xc$‹¼šÔ”ƒ…*8Û˜–0O#/4áLƒJ¼M/)ÂTqZáÕF`ß)Á‹Z´œjŒ#, ˆiQn…Í@dWc ÔB„"h2Vj’RN‘1­C1‰¢J‰œ÷~¤ ^ú.6Sƒ+ꚦ£S™XHX‚Á@Þ¨Î*Ҕ˕δ"L+"†##,3›„‚¬PÂ@‰¦Œ± ­ ’#$Ë#/Ъi9AŠ 4opAßU@lÓÅÁlUò·†!·Ìšpx#‘!‚lU4M#/DM¡¥ŽÇ,Þ)FÛÓH{Ú1¶jÂPsvº#¥¹SxÒj¸±š~ªeé6S6lC9*2š)†®=Ì¢²=<­Á­Ò Qñ'¢F¶Ðjð·Ï™†ÕåF&ÉwÈEö:Ó{‰aB¾˜>˜ˆ–”ãã£AÐèÖ5U!Çš%µ^]²3cX E«-‚6™4Æx5H1Ä#,‹»§]Ä`Ñ°EQ$D’ÑØšgS#/hˆ‚F’ÐlPD—0Á#/6‚‰ TPE& ¤lLP‹{IfäE$C¦µ4H¡PŸ¯˜võŠ%R”Å…[TÒ²ª¥£þ+«ºcTdµÞºº[øÝq=\ŽéÜ•Žù_ |ÕúÛIA¶¢Ûb€„X¤bÁ„au+U,¢xõJ໼Œ1ÄiÐë¿ôm¿0 b *(!"À÷e#$ôÈŽÌ]ÛŽû/U}ØR˜iDó¢_T•YØ>2EB@!‰ŒT£4Ú‘Båµg{)"{*RTCÝ^AÄv̱÷Ø×#,* p2²}ó¤JûØsËÌQ‚\¡¦a•–H%7V•Cדøí½zî,]ݱØÖêêé–‘0mÉè4 g¥HQ¡Š¨6LmÖ 1Ì¥ÆÁî âE1‘¨Å Ò#/}Ò,¡¾(i½40åjçADGp•½u#/.<_íú–Â#aa°“6ÔØÄ»;Éc\%ÞœåöÙ®¼[ÂÜì„‹:)0|^{-k“„‹ •›Í;óJôˆ%lJ«ëþXŠŠ!@tœ§á¯%C°Ë‚ðPÃTP‡XÆî.d•–ó¹pš&£´ü:¶=¹Ñ{ïJÉÐð†*È”AÖ¾ïÆ)í<ãü}šºÀþSâS e«ªïð#ó:±í#,û¨þƒéu°€yì«ìáë8áñ°˜ÚgKÞ?˜û ¿Nº[}úG:HX¼0";¼—ë›ÌƒýÀ`Ó¤Õ…&¤ƒQT*®ï©:ÄÅË7ÜuÞÓ`wÈbŠn½CŒ¢qØ–Ö Ú«U€<çS¥Šš»Š¨TE6±vÖü§+;J ¯âXO\µS†·Ác $èȇ`ò;bY*AØ‚eb‚ Š©ö²Dˆi-;)J¥÷ULíè—-E_ScYª¬±#$ÒgA†þìKÓ!«š¢Ã]µóµžFø7:Däu€âkŒé¤ØÐXE„P!ÈHh¯óSA†ê˜w‚"°ƒ+#$ƒ$J6 šý”+"×´æÖKh·²ÖìKrîíjåb¨Ö4ssk¦ÖÝ5d5¹´›kšÉ®\¶×6w{5ȱ¶M¨1F¨®^,Ê2[†CÜË.ì8–yXCàÀÒ+ï ±ˆÊ25qÏUðfBVAéMž°ò1BöWiÆTÔ‘¶ Ñ¦ô­ÿ ‰.ÒFÞÝ»ª¸ýù>&”ÕPê‹ÅAöJ?@‹—܈~²(P2M@{çø©%¡LÌ"bí È&·¾]ƈƢhb$m% $””B)(ª¡;{‹…xÐ)iuHŒbÞƒ`15"† #$D@DÚ۪Э®“`´­}ÿžÛÑ‹·*˜‰v÷x•lH(¯( ,£I¬‘¢ª¤«cWóoÃ}*‚ Å@éB?ö#$Ò#$š¿‡—HeõÕŒš4 ì4¤l"ãŽOEíiAÕ½CœBRð#$s#$íŘýÇj¶ Ĉ)ÝælJźŽXõTʇ‘ëÐ2`°9@FDLbSâ¨Uµ:ÊZ™›$’”0lbÒÉhÒlY¡µ%‹)II)“hÐ¥[DZ¢­ŠÚŠÚ–•¦jšL©XÕ¢ØÚMlÖóñ™ð­Öä‚ cnµ™¶A¡¸ñ¤FÊäHŸmà  ÆÓl#ÊH8àÆã88cƒxÀ‰ÜƒIP#v#L G•A#/Ò€É"Q¬aŒt„˜“p¨¬M¡²1Œˆ° "c$µ„ˆ(Uƒ£¦L4"%®º²¦éµn­¦Õr­ªE@ ‹]FB‹â*#/@¡Œ³åü9X.ª˜vÒ–„Z (‘h‰7wNìÅõ?"»^–êõÝ›kÂD"¬HAlaVŠ´:ÀßtÙ\Eî±·(D#>‹?˜sì’'eO>¾ßLû+KžZ(¥QJöô RF@‡´.TøÈH‚#/L@p*§¨(6è ž0¢Þ*bcÕ}UPÄûí—¾üQ¥¹c ££Ü¢X†h·áÆD)§åãßYwYcíi fÍ4ó¥!¡#$úH‡N#,ÔÞˆw*ra HKTJ"pïåÛ¥u¼²êT¦e õ.õZ¹¨«bÑUjsmÂõ[´± åï™…áúõ¢nŸÚ¨Töb©4{Ü6̤B’³öiµg0]œ!׳>WZ ƒ@Cͺ¾Ðñä‹äC‹¤¨’.&Žo|zY÷F"Ë`ç`΃՚‚RúÕ ÿ‹óÕ¢4•/!Ô(Kš³ET¦ù5dù5\"ëC#Á­{`êå‰!U²9»ŽÒñÌ4#/d{í.¸Ÿ+';•<ïì·6ÇD!ðJÃíC–·N”'cGçdqáÙøÁ[ƒr‡56ãSŒIótþÝ,êõêD'Þ€ÀX> *5»‘å—Åã°ÏúÑžÏdW£\n†èª%·fzET¼R!#$êŸÙø¦”[#$]œúqåc6:b›tu«0bªY·©|uƶ݀ ´á¼»³Fz빕Z•Ì'É\pþtÀÌþS>88ÄØ-,¦bIN7.ÚSÛOl:Ûgæ=þãy®®wÛ4·Dá㊠†d)âULµH÷ªÚúIv„æ¦zú½ËZá¸j“üêMÁ.™~2 ³Ï#,¾îâè€õL>õf0²iøÚ»ˆ‚DëìÖ–ÉÁŠY!b…SÊÔT¨l ŽpÎ,—5Ò›ð=xÿ½~<á„æÎY™ÒŒ=NÚ›òe7éÄÆË4{„.eÖ¤}¯ikÏ}Ê×ù;ØZkpíï‚]…A¸ØwíÑAy.N¾¥6»mf%®®&’0Æ.3KÇ4ajÎe¸×l¤ŒR%B¢˜!Äg ÷7ÑY kO)*^ó€ÞG¿W{¼K2L¡Î¢+¥"ææåöA–ÏXà¹GqÌ|+¯N™Æî’I¨™|ø¦kŠë™)Ž„žè}¬à#,d*ƒC(!˜­—ÏËŒðxYâ\Û[NDÊn+š•ÇÙ¾Úxm±lÖ2a$3¶ü@ÕÇ#,xzk}"r?ÿnÁ)‘ž!šÍÑJ‡C¶éª žžI$;º/€O™æw*«6ó BÄ÷ÞÔXt±ÃFú„˜%Äï›S1LN†Ëv6ÜÞ†š,ÄÙšÓÂôåÝç¼öÃŽ•#huyUEÖô÷¶3Êu•Ç=˜©ašâô‡~ja67{—}b¢;¯Deð™iÆÕù<¥~øóäìê¾È:]zÌc¼_¯¶=½Mû†þ)„K8Àì;±“ÑñÆåvXÂq²XÆÝiÅŒá1ЙA0Ì™\KO±3µ½fÂðÁCj0½§#iäGQÌ1“l¦:ÞÂÊnvyS»åÉ©¡‘Ë”(”4·´¾+] o™’®¤¸wªd<ã´c ÞŽ>yTlÏŽ1'À²™‚q^Œº¹í¨)¨@m¢‚ì…Bøˆ–¨°ÅeçlJH:aµÝ1œ9"wÄx]É1¼yÊf;¯KB+Ä$gBÅÀ×JëÖº‰9¥#/¨ÜÑ)®þ Ò' ãÏç¥ÚK°Ø¡­p9`s&0¥û=š„"¬0ÔA”°d8ã·)κÆéáÎ׬.7(fóG ‰%—P@7VŠß­rªv ch9#,ÉÖº.í°†(ÐÈ#ÑLCö*ñ#$€@=œ*€€‰ƒX*€LhÀa-HñÜo†ˆäb徺öuãŽYؤvfr(Z–nUÁ·blß*sÍ+¨Ô¦b‡,#$l3H#/"Ï{™i†í¹¦6D%fÌî\Ⱥ«xšî`äð†©Â~V¾hÈ&¨<¢…C:¢ëof§°è•ÍÞN;-XBˆÓnÕa¨Ò3“* ã x}J°ý3ÉÂ#âa3a_*TÎ+9÷çÚ‘å¶]'`ã\éµÎ£it°ü¡ÛÄúÏòghæz¢Çc¢¥¥'¹åÁ¿X梄QU6”ETÔÓ‘¿Šj,Tý¶çeñÙl¶žÐ|dpCÚ×^•µ#,¾ääãÃe~ï.B`§:,å/*'”3´}«çž²¡æ°™˜–†(Ä¿¸ÙÈ…>õÈùç¿Ñp²9–žfª7 ­Zæ0ÙºÞÝCë¡ß’šÖ‹NÚ21D‘ª!ƒŸÊ[Ø´þiU‹WÕGb†gø–%õØ#u¥Y­D´Èæø}åÌ[˜âtÍq[b0ÊV5õv²f¢ Dv:e£;F#/Ç—MÊìÜXuöé鉾Øb¸Û~«#2.Êü9ä‰mÌ`ëØ5„/$uÖ¸Rûd›N—-¿©Ž(êku ý¸«Ç¸ŽŽyßFèYóÝü­Îòæîü_hÕL0xNq]åÒÞ3—Ͷ •#/îñ©4vK#/z©ópÄÜB^$wÛ¾ ¼§î<’¶­P®2yQ†g¼õp`rÐ¥‰K©¥«Ó@¡ö™ÓIè5/Œ5D4·ŒÅ› ÑgQÏ%5\‹${qyÎÖ@”ç‡ñvÂÚjªÖÁïh°ìYÑQnèôz2wo.†O›œ‘Û Ì—z¡ÓG è¸Ba#/7Vœm—艬5<µ¨šÐãXC±{Hç¼¹a! ®YµËÇîã`P—&c½ÁìuÙXg2ŽNÆ·^ò……—Œá4E!N岩«¨T45à£È¶žÎ&t‡L‹=ô«I°nyr%!)¢ðBÊnLZÜPjb\ S­Šë#$åPÍ}·XñËe©ÐRßåæ*Æ1ƒK+udˆ×/¨ÒÁí¸i¶í®o Ü#,hÇHiþ£f-+°£W ¾SJ§ÃÝ:kN4bJ³ÄðÖ:¸`@¥,׆cÉ –(2ƒtHqbePDiòãOR;Æ]ÓxÖa%‚dHÌ¡LZLÝZcÜsd0¶nlcoMÝÛ¼ë¼÷ó^"ÌÉ®°€J墣ܧñyŒèœ8øÜ<#mŽv4Þ¸í5+‘Z3x#¢Ù7T€±`,ip QáˆlÇnåÁŠf¥n0±7#$£Œm×±—¦¥4ÊÑ׎v²ÍîFjh£MÔU¬zmkZ¦A¸Lk.<“­†µcÔès‹œÕ²·Ã&ÛØÅ ®* Œ#/kU išV,p^,u— Mµ¬Ù¶Ød™ÒZü·Æµ9ç'»0ZQŒmÖ­8lT†¨(Du¤÷òžÞWjn—MÖNrdצìx«¬bÕÈd@`ÑdmÖBæ¤KÀmeS\Êùf•“%+XIw­Ü&]J&0gHnÀot‚Çßh­siH“°N'a§#,tÔqë³ã†•DÕ)l£{*5FGáxHéòç1cSˆ‚ò£œµ.¨CZF†™ÁÑ •Ž5„[Fᔤ(U†A£q)¡ÃH`Ú`ÚbjWZ6óqmäÉe•ÛÓ†ml&åÓãA €ÊÑ#,‘R¢µÕâcÄU­’®PÖˆÑa†Qª»vÝÐTcò|f¨c¦ƒ©¨-9þ£ÀÑxpJÖ^ûË{B¡¤aMÆ\zâ•XÑ\‘ä—…Fø•ÞŽ‘0&–i±³¤ÃTÃzÓ‘2Šö»íŠl•5R9yn°¥#/ÓjºÀî0XëF3BÖ‰ÈÌg&)èÑ39¶¨‰›—éÞXÌKGGoËÅÆ&˜Ì-8^UU¬DÑ+oõv§üMè£Ú#/Ô}+ÌÇÑ”Qôb,bQîE£ nÊ`¢ç¼#,4õb7°äpÇ2š4ƒææ‰#/pôÛÅ…³)L8…Ù 4ÃV3;¦Ú4\Õ…jàË!ìižá#!Ï©,ÙÐ{¦¡]L‰Ž#o\01'BÌðCV#/æebkw9*hÛ2B#Ñ*Œ­N4¡®2 Û#;ì‚›ÀÈÔjA¾ÚÌCYg@½:Áx0ÄäYr!¥vªŠe¦ãäÃ37¶-íã"=OtÓáôr~MT¦Dˆ‚‘)GieÝCc'{sÅ4çÈ4ømþÐ…|*P1DŒÝ?%«õl¤×½®ÛµÊâ¿*çõ¡C¸PìÝ<-Q‚}¦NhSÆIUc65«p#,!Š”Æ[v~ó‰A„Šªˆ=þ•}ì)êi¯Éún¬¬Yt錦«¸Iï:°÷ŠtŸJ¨†Ÿohm“¶‚2H;+ ÒÔ ä#,O¯³ÀždïO#,ÉF@ghóöyzÕg§‹ç™œ&·Úrkm-0x·ÛûÚ«Ë%bƒeª•ÁåÊf{¸Ï~û¾î¯G«¹né;»“ˆV†‘ª•UNyg›lòõ®þS³€ò)G˜¶´0ÕBl*‹I-ÒŠ!b¥J%h–(!öÜì:nî†&£® Ô=7Ï#/BA¨ö„6¼Áh@¼‘¨ÈŽì¶’’®Õ2–­/.¹«¡DmÅ#$QTŠûÓ#$6þºÉ<yÓ²»kÛÛW¿¼’$ƒ!# ”Õ#,2ÖØlcdƒ1ŒLcH‰RPµL«ÒضKImX¤£lIY4aE6Tm†m#/i©Rl’šQ *#CZ#Q)Ñ’Í)²)TÑ…¤˜m†0‰JLhFI $#$Úoê7gà_Îd<ò=‡#™¢‹ì‰F<¬Þ“µœ¶Ÿ|Ì],d»h+õÍ?$$fï#,ä7ÓÓßm/ª¸›=W)'£€ HZÁÅÀõÅ#$*ÀÚ†`À¼HgQT6Ú©z›ì†Œ]ƒ³8ç#,0ÒMM«så©÷ÞšìÜþD»ð;EB@Y„Õ³hÞm+¬ç³© ÛE1Œ$%˜žŽ²òI!uF«[È÷ùøäˆ>ý:¯?F!Š¦UJPåmN‘üù»zOÇs}M#/5wÆ÷ eþÀ> äÈ#/#$(‰$Fhˆ¬ ˆÕ%¬Qõ5ZæÓcR…&£F+b3õªB£#$`„,P*U#ëK d]ø†Hza“,)H0©C$(ü}¹ÌÜmF‡õÌ+ßÀ¸6 ú B¢;#/-CLÄa¹óË£Uø8ºènWUx#ÆÓˆc¥¡Õé=v#,"tñ> ­MuòN)Æ×%yꢹ`c6=¤„ˆEï9ê,:±Û¼ÖãØ»/ÁyÉÄ0†Î„"¹|$0ez¢¨‰T*r=†½Iþ™›ó0l8î°)¸ÁбÚë w—Ô¡¤ÍžA‘éè#/pÃâÍúU°ÜªxYôw—î#$ÇÈŸ¶Äøæ·ÑlgæDH%óŠºKLì¥+Ö"VG¡NhƒŸÓÎ8Ç_R3–BÁ¹‘mݽšÉb2FÈ[œ¥BHÙ#/ßyv+ô‹k¸XgÅ›”§vê"ªÞ~˜œ¬çLðœ424ÌÀà(B– #"©#,wKÞ–#/¨ùÕX– ˆ_õbER¡ó.Ì‚òe·"ÝꋳRU#,L¡“D‰²I#e#¬eâ؉¤8%–qÌs»#,B3eæh@ e /HaÀ\â–v£4‹ZÌ#,(¯X•3W½5Šk˜yt<âkØœ5Ûy'׫ÅÌ›‰¤OIÒjV¸é:±h„5eá .W8zÌíTS€ìˆ‚]9çRÌ•*8²Òëáεl.瀵µæ#/Íø§•»;Ñvw*­ë®4ŽE]Mtš@šŠÄP£Q»1#l™°rS¶æ9àtԷ˦•..g[8##$ã¬;˜9õ :Þ¡ºq1–#,ô"#,É+ˆ‚Xw#ðtK†£G ð ¼Ì–³¢p&H ‡X˜”÷‡\³2)ÏKLSWËj>boÚ3‡’dà–a[&½œ&Ú7›ð, –VJMjfÁ‰LX|rÜX[[ï˜#5…0CL+ ó×7íßK²¢’#/ɽÛ£%š‰’QXÊêç³Y4žø¢§®8TŸ(â«$3@ä½Ì·gnªÕ ³ ŠP—JPÍ KqĆ™gl•ª¹ƒxgAH#/LÄ#,D4(4(Ñz»ïƒ@ÕÛ‡ˆ¨s° rÓmSM–\ éˆko•LW0d‡“êùãQ¦;r²9Mgd×#$ùa5)©“2:rg¢'—”+våÀu˜h(?híÓµå™Þ¥Š–vA=3±8LÉS.Ž<˜9ÞÝ“M7ß%†8Ž9Ê¡Ø-t†„ŠÑ‹Î®¯Ñ®*ß‚’w£|9S 2 ŽT¦æãºÄsBAƒ 9#gé:0*7¡®‰#3ôI4É"ƒmIEHy!ŒU4"ð £#,$\U(j˜fÁàž”ºÄ8:ðšÑ”`#/ÎÓ%ïÔX€ëåÙp,©ˆ6aÔXd–2B"$ÜЗsQvSBkÞeÉ€440|ȹ)‹¨Ä9fŠDV1#,„-ŠSWHhM%™6Y* ân°³3,UD –Ï7Æu5z­2Ò‹]muqvÙ‹ŽÐ©•\tC;$—j2 *#,ˆ¢}Ø,Þ@²"ÆÀéF†6,™)šodADàbPßnê²2B5ai[*› lN!@0N#$\a¡ÔÒ;¨HÂ4WE‚šI‚j`6%Ò"&#¡œQ´3#$€¦ˆ»àSƒmµáɦLb(ä3t!ʼnE@78„…EÕ3*L"[!agE"‘b ‰>ÂyyôŸQkk£U@Ê(¨ˆ°צp†ðå·ÃÁ~¢Xjû;D!Ö#/,"B@M@*#$Pä@=·|Cr«˜#$pF]#/öâ¡qQ#,¬Ê#/õG•¯Þ¦º%¥÷1ºÉÑA§ùhÁSpÅ€åÓ™eî7ÇzŽ-žÒbÚ9‘Ýt+€v¶pÌûÁ±w¾•"f ž¼j™ ƒÁ›ÙÓô¢©ù} #$:ñÖ`äò°i~ô‡6)«‰£WÒ¡$P¨)Nááó¬Ã ) ¢¡š Õ‡@{Ç®ÖhƒùmÞšdà<Up•w%DÈï.T‰Ã•”8‰‘¤Ujƒð²É4ÇtÙ’žUlEôHšdÉß“µÛsÍZhñèîvgìssÈŒ8"s˜¨!š€´#,TV(NASeôjªÖè+Èämμa·4}o{žVv³XÙˆ¢È¹»ÒòFûêÌ¡â“ê“ê¯ô3åDŠ§²Œwï~Ò§3Ž;¤Lk#•ô×Ô=ÑU, ûbË!·GÃœ½Ió<ÎÐ}ÛR1[ '¥|.^I#I1H5$Ô²Ó¬’”ÛXÕ˜jaTÖ˜ÛjM¿q¢µqœ×CF³f×[éßrÝÙé7¿V^`s)pé‹&©M#$ñ7ÏÆ›h¯mNCM‚Ô¥¶‡š¡ÑŒ;;‰&i”ìLíÂÐ 57M'w G²•Ë¹,:"l ÕÀÂœqx4¹km ëEƒ·ÂF#,É&F[-ß]\g€{ÎÜq³!´€Ø:Ò#/M )kƒRÛ9F!¯)è•ÀˆA  Cë§Í"œåÖSˆÜ€¡#$PYl±’Ú!V\Î9“2ëCcòÔì󊛞õCÓ2!ƒ~à¶-V ø ¦VEsv*5 ßÞ­h`±f-V°àÚ_q`3÷3[&2ÆEô²Ð³cð1#,Ç") ‡—Êw„¸Yí+¹gw4 )@vý* tÔ"Á&R:X*zö™‡€z/~q“º0ºcxTNA¬O#$Š##Æ#$Ž@ U6<ãÊécàwæŸAB^[oòýV­ÙF]˜Ïº‘СÁ}-ÈÙ(¡+Qµ”Åo{‡æ>âžÿwÕÜ{8VD…»ŸÝŠ/xžà ßÎÝ÷¤‹“ÚJŒçã±K€kÖùÍ#$‡ˆ ‡¶’ÍšøÙCGGc—ÐûŠ*#$ÜhSéŠk ä:¢A'0“º‚åÈÃÃËp!,â#/ Y ˜ÌQ±£I.êè$6F™_Gy‡êîÚå\Üç¯7žzî-œ4VQMÔQF%äÝÍt#/ò6M¢«ÅÍrÜCÝݼ[Ï+´­)P³¿ V%FBj'êH¦±„Í÷íú~g¿ép ?}ÿšŸFTþ!ﬕ0O#?¦ùÀ0§˜Ë¬:t @Iˆ±bŒT—Qð6RcÐbZld**R66‹!¥™*›6¯·ñÅFúµ_¹¾ƒH(Ñ TÔmŠ£iJR$< #,ADA2Kaù ˜`##$ ˆ™|á)kYêâ\]O#aMGèäK}ÉùUð•ëMÝsdScXZʱF±³#Œ¬TÊ-– O^w¶“Z•6ˆDê¥Ñ@‹¹F€/n‰§û|LÞ]„ö>_Gñ:±$ê÷„V Þbö ñøë§?Ž¥;àK!?7\`$÷‚ia<ˆ=Ä‹v˜ô §G,¦‰"÷žjžýIŸ¥^Ûý¸Å…Œ„)RtiŸ1þB âfçšL ä*`,F)ˆK'Ùrkå«×p¨!x#,³#,OEMJ?ƒDÁæžÕj„‚òA#/Rœ†ÓF‚‰"‚Th„DÚ“JMRÚvœ·W¾í昚6Õ¬˜#$?¿#,(”+и^T§¸¥Y»Y–^Í zzÍ|ª‡Û ìF)ÃVxÝ¿pbܵ™€­*#€Ñ2óP¶vf¥£¬m´‡>t' ¯Á6 ´Ú ¹´;m^‘ß--òlAþ:=êå½áÓ¤½yFÆ?ª’8æÄ} 0eƒùXÐHX÷"½?åWû#$ƒÅ]5#L"Å)¦%I²5¶1R`¨ªM¶´oÂÛ}­^&ÃEh£i4ÊaŸ#ow ¨ËD)#/¢FÍLʺ?#$¹²Æ9T(ŒLXQ袚&f½…‚À K»P›á>QËrì×/mß–Ú[[ø*EkWš±­F- Ú”5F„«6X‹Xµ¡c„B}D£Ì᎞é¿ÍÛÛJ¬²R!ùxßî¾3`~ºÇúc )p¡4¤»ÂŒjxÅݤº| cKî$ú{dU¶iGlüï²Öm™bJ8,,‰ˆ"rÍÛŽðÉ€ÜQD“„ñyb¼êºoo’Ýf“SE*[Öl+¶Ùk»²¼kÍåkªmMoJ¹*-æî³7feW\ݵsµ–ȳjòîÆš&×wWw[I²¤©‘)“hV@U#,V$©ÁJ°ÁÂòít7-äMäÖ˜Eé½yq©M-”Ô™e^•®­çW^yÖÛÆ£YFS-e²–¼îå»]Û¢Ë[.šé+–»sÚðÝ28x€b¨µB˜úÐKa#,!€›4A?h×Uf…Ðj‘bɸ}…ð£!ãa0Rö´lÏT©¶®~ •#,¨þ}4™KhÍ¡ù$Ê AT.^ôI7Œb™™°rÙ†8c~ Ó^MÏ-»çÉr{uþ×äºpõBK°’r#ÙéÑ=X'la%¨‘#/ÛŸº÷#Eí3É×È—R›`‡TkÏq.$-ݯò|2 —C2¤M#,UJœ]/„èαoÎ÷¼#,1¦‹}ž&f¹#/v}ÛyD"Š8®QHÎ%ápo¯Rcx¹kõÞÂMN‚$aTÜ©&Ž>9˜Ú¬ˆ»¿‡ør’_á#£4Þí#Z¾‡O¤•—uÒ¤õÖö1üˆ¶$à×€H0l1¢7!¶dI§ßô<äÕàñé¡}M@ðËd)™&3/…Sã=MÃT¡óY§#‰I¥ùš¯C"JÝ',=ÓÈ®‘ßNáâ0ÎFW£ÃÍ`”)ݬú%‹0'œÜ Ø#Z V“©%°TR7Ô3rd5&G±:ÄÖº0ˆ@ëÙ©˜@Ç‚hvÉf}=ð+zC‘bøUÒ‰ŠQ¼J–-‚%¢–›ÕÕ™Öÿ×8kèú±‹ÿˆÃÚìú:9v'WwN¬òs¨÷ùQ“¤0é ©’Ñ% ¹¹8w8')©ºþê¢XŽH=žnY)a1Ο 궦qBƒš¤hÉûR\µ öÔ Ù;ò«[y¶ Ü(dÿ‰BÌ7EN@Ä®”Dqx‘·¢ØjtïNú¨T#,"ÐÍ@Ôb´¥àp1õɳy®¡¢QQ).ÖÃ@ÂÇA lÇ¡ˆÞ–E%2‹D —æx%Î\¯†E¨ç™ #$Pl~&NxêÍ?ôç̪÷°»@HHöšد#¡Àz B+î…œŽÓÇݘ€ \‘‹5ÁlDXÍ-ïMž¾¶—•(Px¸Š¨“ìÂ!h@Aü"eðÄ &xÐ[Ó@(ã 4†Ô#/<²dëúËB6WŽ¸ì ä÷ä|ªý€ûîýû6Gε©œ’2¹1P˜þ«*¶€Oý?úþïÕöÿÏÿÓþÿýŸù3ÿ£áçìëÿÝÿ£þŸÿuÿ÷æÙOû:ÿüÛËüÿÏÿßÓÿÇÝþñá,¿ãüåþ_ò×ÿê_ÏÿoÿïÿŸóîúÿç?ó÷ý\?åÿ/“üÿÏþWý?›øOúøþùþ¿ÙË/ðRCì§û"a â~ìOúŽÐL@Lgé#/uÅ1 Š¸úäE7¨;H‹ƒ»ƒìŸÙe#/ßC#$yMc#$ú•EK^÷¨·yüËøsôw;º‰$ 34ØŽ‚ÅN1¨ ªÂg«ÑT¨qB ³M¢ãÈä…LŠp ZhWz?ÍW–X–@N±ÿFíÛÏaAsHX¶æð#,¶àÕý@â÷EÿH“ äG^º*F  $ñÌA)§™˜`;u‡ò‘(Uòh$×v¸æû2üÆW/šÏë¿>7ÃÈ÷µMâzzÊ<5†/2­«ÿ•#,Ì´ ¢Át¹ x!)3 ±¯œ‡ýɨnÁ‘ÞÞ8ߺÿÝ[¬£ Óã-iŽc¥n²3¹[3?``Ú•5$C[#^½ÖinÍŽ8ÐÙiÐïà•0c 6áÁ£D"™U;Ú7­¼WÖšD˸v0&î¡#$ѺhWµ—R Ke±‚TK,>#,<Ù”Þ¨v á×ÊxøqísL( Ûlr¨3QQB±i‘4H]µRa&ÅÞOt³ad»’ LÖ¡·ÕçÕà«œÞ);¹Îˆ!­6vuaËá²oES|ê;6UNg1'‚"aæíÂ]Â’ !‚®W.ãÍïÜømà kÁ„ª¨´“<®€íþ?On|Çî¸Ñ¹=BÆu™¨" ª³ ¡I=8òé#1½ül`#/°Zd†6á¹R¶Î*ÒÅ@ñdŠX”_¥›U€Á‰ * §¡Ù:Nœ%¸J’†6i{Æ?–\FfpÿöÅåËäÈ/ÒÁËi;uÈ ˆ„˜qÕJ†Ö ™»3Ynîu¨Np„£Q!YH˜Ô/‰¨”5صf”ʪ6ÉTfi"E…‘S_EÛWUUðøu­~³®Óï>áÕþhÀÿZ¦è«y‚ÒJ/Ûî_‡u^Ï[ªmšÚ½Ý>€ÝåÉúOöHÃ8/×-åo¢×Cëuj.ba™ÿg™Ï¼~f½7*©ˆÄQŸP•xøõ¤ëÿHワí›Õï…¬äúÃ$tÛ%Œáÿ忲†Ùõ ÏO²zB3–9 >¹IÚÔÞŠï…@×–f­ÜT9†P^]*zgâ_£¾³ò‚Œðf™Ó%› iSG†o£Â f£‚0ŸUˆO¢áG½\áU±´[¢òÍe¯¦›×æl¶ƒ)JotÆÜ6_” $Â[â¶ù۲ƼmIo¼®cbÑðm¹µŒoméF¯e«zš$,‚©#$Ò0… RÍnÀ¼Ý‚ÛuÂBƒ‹‡$9¹bCf˜§Æÿ”…á·…8IÀ#,¦.D·Ge‹Ãvâ…˜P†%<¶l$½úÈc,ÊÕUªFFz©hÚÄÓÿ¼<ïÙt]ô¤‹ 3hä)_îùÎÞï›(ôfóGj:>Î"øñ(ÀOç`ÁCÐ?F¡þx¢ÅˆÇb;NÝ¢JP¨°DaÆ%P)‚`ÈEˆB%ÍH æB@‘I E;½žï†G—Èú>hiFBtïø¡ñ}}­wÑÓNÓ2ùYiû³ˆ ^!ÃGF åã,A‘;þßÀ?>ÿÃÿP …çý}Ÿ±'Aáž'ԂȤFOý¾@P‹_ö¸sX[þTþßõ< zÈbe ïÿØØÿÖôÿVÛùt‹<.Zþ~Wöÿõú¿ð»OŠü|!óa§Ž„æ¯TrâCΗuÇ™ïøuÐw¡ÃàÎ@{9aw§×èä8¾#=ã’ÿî°y¹#,_úÄ+?B[2D?_÷ÔœØ~ç¨~Ë#÷i‚SþÉ+u#K7±r…unŸÿ^ÁŸ#$Ê =þvbã¨:'R’í²ÛRýôZÎJíâqTE3‚o³UÂã,æ#,L;äq¦Ó§m3 ÊÊÇîç,Má†/-„±¿Ñ8¨–¼­§0ayþÎ$fu‹^;ÙWñzÝvd±KÖMqAuõû|‹31éÏco#´Ÿüý»Ÿ#,~Ÿø«#ħ¢ŒäÅ#,¾ÓÔbI(P‚5Ö®§üD*žÑð{¾¯­" ÿþ.äŠp¡!£à¥z +#<== +#-----BEGIN PGP SIGNATURE-----\n\niQIzBAABCgAdFiEEivIt5aBoIuNHTzxwSbTGfAUneqoFAlyFMaIACgkQSbTGfAUn\neqoHkA/9H11S84e1r7tI8QGS15XwN1bV3KR3guTtnIAt+TaILfTne69BNMZi5iA1\nkRzKt+QcCfjI3HsV5pLJ1X4y4FZEPx4kRtVkFBZYEskl0MNwRLQsKyVEB9T9/dhb\nGP36OFXirG0iGg0qu8IaUsSLfAk/dW++dYqfB1T704FC3LyN05ijMsu5m0hTrTQE\ncUbNbj5cm9gifkbECuaIJQEhvM5TCMR1r8yoWINtD9gLKwrbNAv9f4qdFpqooLRL\noLSPWUSzcq4jkGM4jHosNh3kza5CNoGPsL470tL4u54BgIJuDO8aWAO7pDKWJgn6\nswuVol2v7QvlEb4ejErhP65yYwHc+GbDcY4FDTzL24yt4p9QZils7kAtojIsOIv/\njnE4BpJA44ymB0SKIJbK8VJfT4O71U2EayXGvSpdbGRQt0wD96wDsexLXNPoT+m7\nLiQABIJrYYMZPd6TR6czolS1PjsIb7UTIw3sF16G17xuPM0zDxlULCB2D/eMCU+G\n3xoYj0EtNY/A+xpWQO9lOQ7LqJVTjSChDFDajguslY2vxD735xbGDbGCLtAPQRjm\nVFC88WTnGy/cZ3fFlfLdaCRhpu24y9WVlTYgchSBV83gkD9gnJTvJ4q17PKUvxis\nBMysLiz9gVqT8Ic6xbCThRQ5K+pqvn3isYxz/iEm2zGL1/V7PuU=\n=wpUd\n-----END PGP SIGNATURE-----\n diff --git a/wscript b/wscript new file mode 100644 index 00000000..ba7542af --- /dev/null +++ b/wscript @@ -0,0 +1,149 @@ +#! /usr/bin/env python +# encoding: utf-8 +# a1batross, mittorn, 2018 + +from __future__ import print_function +from waflib import Logs +import sys +import os +sys.path.append(os.path.realpath('scripts/waflib')) +import fwgslib + +VERSION = '2.4' +APPNAME = 'hlsdk-xash3d' +top = '.' + +def options(opt): + grp = opt.add_option_group('Common options') + + grp.add_option('-T', '--build-type', action='store', dest='BUILD_TYPE', default = None, + help = 'build type: debug, release or none(custom flags)') + + grp.add_option('-8', '--64bits', action = 'store_true', dest = 'ALLOW64', default = False, + help = 'allow targetting 64-bit game dlls') + + grp.add_option('--enable-voicemgr', action = 'store_true', dest = 'VOICEMGR', default = False, + help = 'enable voice manager') + + grp.add_option('--enable-goldsrc-support', action = 'store_true', dest = 'GOLDSRC', default = False, + help = 'enable GoldSource engine support') + + opt.recurse('cl_dll dlls') + + opt.load('xcompile compiler_cxx compiler_c') + if sys.platform == 'win32': + opt.load('msvc msdev') + opt.load('reconfigure') + + +def configure(conf): + # Configuration + conf.env.GAMEDIR = 'valve' + conf.env.CLIENT_DIR = 'cl_dlls' + conf.env.SERVER_DIR = 'dlls' + conf.env.SERVER_NAME = 'hl' + conf.env.PREFIX = '' + + conf.load('reconfigure') + + conf.start_msg('Build type') + if conf.options.BUILD_TYPE == None: + conf.end_msg('not set', color='RED') + conf.fatal('Please set a build type, for example "-T release"') + elif not conf.options.BUILD_TYPE in ['fast', 'release', 'debug', 'nooptimize', 'sanitize', 'none']: + conf.end_msg(conf.options.BUILD_TYPE, color='RED') + conf.fatal('Invalid build type. Valid are "debug", "release" or "none"') + conf.end_msg(conf.options.BUILD_TYPE) + + # -march=native should not be used + if conf.options.BUILD_TYPE == 'fast': + Logs.warn('WARNING: \'fast\' build type should not be used in release builds') + + conf.env.VOICEMGR = conf.options.VOICEMGR + conf.env.GOLDSRC = conf.options.GOLDSRC + + # Force XP compability, all build targets should add + # subsystem=bld.env.MSVC_SUBSYSTEM + # TODO: wrapper around bld.stlib, bld.shlib and so on? + conf.env.MSVC_SUBSYSTEM = 'WINDOWS,5.01' + conf.env.MSVC_TARGETS = ['x86'] # explicitly request x86 target for MSVC + if sys.platform == 'win32': + conf.load('msvc msdev') + conf.load('xcompile compiler_c compiler_cxx') + + # print(conf.options.ALLOW64) + + conf.env.BIT32_MANDATORY = not conf.options.ALLOW64 + conf.env.BIT32_ALLOW64 = conf.options.ALLOW64 + conf.load('force_32bit') + + if conf.env.DEST_SIZEOF_VOID_P == 4: + Logs.info('NOTE: will build game dlls for 32-bit target') + else: + Logs.warn('WARNING: 64-bit game dlls may be unstable') + + linker_flags = { + 'common': { + 'msvc': ['/DEBUG'], # always create PDB, doesn't affect result binaries + 'gcc': ['-Wl,--no-undefined'] + }, + 'sanitize': { + 'gcc': ['-fsanitize=undefined', '-fsanitize=address'], + } + } + + compiler_c_cxx_flags = { + 'common': { + 'msvc': ['/D_USING_V110_SDK71_', '/Zi', '/FS'], + 'clang': ['-g', '-gdwarf-2'], + 'gcc': ['-g', '-Werror=implicit-function-declaration', '-fdiagnostics-color=always'] + }, + 'fast': { + 'msvc': ['/O2', '/Oy'], #todo: check /GL /LTCG + 'gcc': ['-Ofast', '-march=native', '-funsafe-math-optimizations', '-funsafe-loop-optimizations', '-fomit-frame-pointer'], + 'default': ['-O3'] + }, + 'release': { + 'msvc': ['/O2'], + 'default': ['-O3'] + }, + 'debug': { + 'msvc': ['/O1'], + 'gcc': ['-Og'], + 'default': ['-O1'] + }, + 'sanitize': { + 'msvc': ['/Od', '/RTC1'], + 'gcc': ['-Og', '-fsanitize=undefined', '-fsanitize=address'], + 'default': ['-O1'] + }, + 'nooptimize': { + 'msvc': ['/Od'], + 'default': ['-O0'] + } + } + + conf.env.append_unique('CFLAGS', fwgslib.get_flags_by_type( + compiler_c_cxx_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) + conf.env.append_unique('CXXFLAGS', fwgslib.get_flags_by_type( + compiler_c_cxx_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) + conf.env.append_unique('LINKFLAGS', fwgslib.get_flags_by_type( + linker_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) + + if conf.env.COMPILER_CC == 'msvc': + conf.env.append_unique('DEFINES', ['_CRT_SECURE_NO_WARNINGS','_CRT_NONSTDC_NO_DEPRECATE']) + else: + conf.env.append_unique('DEFINES', ['stricmp=strcasecmp','strnicmp=strncasecmp','_LINUX','LINUX','_snprintf=snprintf','_vsnprintf=vsnprintf']) + cflags = ['-fvisibility=hidden','-Wno-write-strings','-fno-exceptions'] + conf.env.append_unique('CFLAGS', cflags) + conf.env.append_unique('CXXFLAGS', cflags + ['-Wno-invalid-offsetof']) + + conf.env.append_unique('DEFINES', 'CLIENT_WEAPONS') + + conf.recurse('cl_dll dlls') + +def build(bld): + bld.recurse('cl_dll dlls') + + + From 467899b99aa225a95d90222137f18c141c929c86 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sun, 5 May 2019 20:43:26 +0300 Subject: [PATCH 194/211] Set activity before SetYawSpeed so it has the right activity --- dlls/monsters.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index 953d1a69..3ff235ee 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -1208,13 +1208,19 @@ void CBaseMonster::SetActivity( Activity NewActivity ) iSequence = LookupActivity( NewActivity ); + Activity OldActivity = m_Activity; + m_Activity = NewActivity; // Go ahead and set this so it doesn't keep trying when the anim is not present + + // In case someone calls this with something other than the ideal activity + m_IdealActivity = m_Activity; + // Set to the desired anim, or default anim if the desired is not present if( iSequence > ACTIVITY_NOT_AVAILABLE ) { if( pev->sequence != iSequence || !m_fSequenceLoops ) { // don't reset frame between walk and run - if( !( m_Activity == ACT_WALK || m_Activity == ACT_RUN ) || !( NewActivity == ACT_WALK || NewActivity == ACT_RUN ) ) + if( !( OldActivity == ACT_WALK || OldActivity == ACT_RUN ) || !( NewActivity == ACT_WALK || NewActivity == ACT_RUN ) ) pev->frame = 0; } @@ -1228,11 +1234,6 @@ void CBaseMonster::SetActivity( Activity NewActivity ) ALERT( at_aiconsole, "%s has no sequence for act:%d\n", STRING( pev->classname ), NewActivity ); pev->sequence = 0; // Set to the reset anim (if it's there) } - - m_Activity = NewActivity; // Go ahead and set this so it doesn't keep trying when the anim is not present - - // In case someone calls this with something other than the ideal activity - m_IdealActivity = m_Activity; } //========================================================= From c27aec4c9c30341cba1f2a217028cdf1464d0613 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 6 May 2019 04:12:12 +0300 Subject: [PATCH 195/211] waflib: xcompile: even if hardfloat ABI is selected, force architecture name as armeabi-v7a, as armeabi-v7a-hard is completely virtual. --- scripts/waflib/xcompile.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/scripts/waflib/xcompile.py b/scripts/waflib/xcompile.py index 71d05ca6..b72d87e4 100644 --- a/scripts/waflib/xcompile.py +++ b/scripts/waflib/xcompile.py @@ -31,6 +31,7 @@ class Android: api = None toolchain_path = None ndk_home = None + is_hardfloat = False # TODO: New Android NDK support? # TODO: Crystax support? @@ -62,7 +63,7 @@ class Android: return self.toolchain.startswith('clang') def is_hardfp(self): - return self.arch.endswith('-hard') + return self.is_hardfloat def gen_toolchain_path(self): path = 'toolchains' @@ -124,10 +125,10 @@ class Android: cflags = ['--sysroot={0}'.format(self.sysroot()), '-DANDROID', '-D__ANDROID__'] cflags += ['-I{0}'.format(self.system_stl())] if self.is_arm(): - if self.arch.startswith('armeabi-v7a'): + if self.arch == 'armeabi-v7a': # ARMv7 support cflags += ['-mthumb', '-mfpu=neon', '-mcpu=cortex-a9', '-mvectorize-with-neon-quad', '-DHAVE_EFFICIENT_UNALIGNED_ACCESS', '-DVECTORIZE_SINCOS'] - if self.arch == 'armeabi-v7a-hard': + if self.is_hardfloat: cflags += ['-D_NDK_MATH_NO_SOFTFP=1', '-mhard-float', '-mfloat-abi=hard', '-DLOAD_HARDFP', '-DSOFTFP_LINK'] else: cflags += ['-mfloat-abi=softfp'] # Tegra 2 sucks @@ -141,10 +142,10 @@ class Android: def ldflags(self): ldflags = ['--sysroot={0}'.format(self.sysroot())] if self.is_arm(): - if self.arch.startswith('armeabi-v7a'): + if self.arch == 'armeabi-v7a': ldflags += ['-march=armv7-a', '-Wl,--fix-cortex-a8'] - if self.arch == 'armeabi-v7a-hard': - ldflags += ['-Wl,--no-warn-mismatch', '-lm_hard'] + if self.is_hardfloat: + ldflags += ['-Wl,--no-warn-mismatch'] else: ldflags += ['-march=armv5te'] return ldflags @@ -152,6 +153,9 @@ class Android: def __init__(self, ndk_home, arch, toolchain, api): self.ndk_home = ndk_home self.arch = arch + if self.arch == 'armeabi-v7a-hard': + self.arch = 'armeabi-v7a' # Only armeabi-v7a have hard float ABI + self.is_hardfloat = True self.toolchain = toolchain self.api = api self.toolchain_path = self.gen_toolchain_path() @@ -181,11 +185,6 @@ def configure(conf): conf.fatal('Unknown arch: {0}. Supported: {1}'.format(values[0], ', '.join(valid_archs))) android = Android(android_ndk_path, values[0], values[1], values[2]) - conf.options.ALLOW64 = True # skip pointer length check - conf.options.NO_VGUI = True # skip vgui - conf.options.NANOGL = True - conf.options.GLWES = True - conf.options.GL = False conf.environ['CC'] = android.cc() conf.environ['CXX'] = android.cxx() conf.env.CFLAGS += android.cflags() @@ -197,6 +196,8 @@ def configure(conf): conf.env.LIB_M = ['m_hard'] else: conf.env.LIB_M = ['m'] + conf.env.PREFIX = '/lib/{0}'.format(android.arch) + conf.msg('Selected Android NDK', android_ndk_path) # no need to print C/C++ compiler, as it would be printed by compiler_c/cxx conf.msg('... C/C++ flags', ' '.join(android.cflags()).replace(android_ndk_path, '$NDK')) From a699702c00b7500d86501dbdf4ec5eb0836687e5 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 6 May 2019 04:13:09 +0300 Subject: [PATCH 196/211] wscript: strip lib prefix for HLSDK --- cl_dll/wscript | 23 ++++++++++------------- dlls/wscript | 21 +++++++++------------ wscript | 34 +++++++++++++++++++++++----------- 3 files changed, 42 insertions(+), 36 deletions(-) diff --git a/cl_dll/wscript b/cl_dll/wscript index 85de7e55..a9b912e3 100644 --- a/cl_dll/wscript +++ b/cl_dll/wscript @@ -37,25 +37,22 @@ def build(bld): 'StudioModelRenderer.cpp', 'text_message.cpp', 'train.cpp', 'tri.cpp', 'util.cpp', 'view.cpp', 'scoreboard.cpp', 'MOTD.cpp' ] - + includes = Utils.to_list('. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public ../utils/false_vgui/include') - + defines = ['CLIENT_DLL'] if bld.env.GOLDSRC: defines += ['GOLDSOURCE_SUPPORT'] - + libs = [] if bld.env.GOLDSRC: libs += ['DL'] - - if bld.env.DEST_OS == 'win32': - libname = 'client.dll' - elif bld.env.DEST_OS == 'linux': - libname = 'client.so' - elif bld.env.DEST_OS == 'darwin': - libname = 'client.dylib' - else: libname = '' - + + if bld.env.DEST_OS2 not in ['android']: + install_path = os.path.join(bld.env.GAMEDIR, bld.env.CLIENT_DIR) + else: + install_path = bld.env.PREFIX + bld.shlib( source = source, target = 'client', @@ -63,7 +60,7 @@ def build(bld): includes = includes, defines = defines, use = libs, - install_path = os.path.join(bld.env.GAMEDIR, bld.env.CLIENT_DIR, libname), + install_path = install_path, subsystem = bld.env.MSVC_SUBSYSTEM, idx = 1 ) diff --git a/dlls/wscript b/dlls/wscript index 95581ff7..05a7d002 100644 --- a/dlls/wscript +++ b/dlls/wscript @@ -49,19 +49,16 @@ def build(bld): ]) else: defines += ['NO_VOICEGAMEMGR'] - + includes = Utils.to_list('. wpn_shared ../common ../engine ../pm_shared ../game_shared ../public') - + libs = [] - - if bld.env.DEST_OS == 'win32': - libname = bld.env.SERVER_NAME + '.dll' - elif bld.env.DEST_OS == 'linux': - libname = bld.env.SERVER_NAME + '.so' - elif bld.env.DEST_OS == 'darwin': - libname = bld.env.SERVER_NAME + '.dylib' - else: libname = '' - + + if bld.env.DEST_OS2 not in ['android']: + install_path = os.path.join(bld.env.GAMEDIR, bld.env.SERVER_DIR) + else: + install_path = bld.env.PREFIX + bld.shlib( source = source, target = 'server', @@ -69,7 +66,7 @@ def build(bld): includes = includes, defines = defines, use = libs, - install_path = os.path.join(bld.env.GAMEDIR, bld.env.SERVER_DIR, libname), + install_path = install_path, subsystem = bld.env.MSVC_SUBSYSTEM, idx = 2 ) diff --git a/wscript b/wscript index ba7542af..9a2060b7 100644 --- a/wscript +++ b/wscript @@ -21,15 +21,15 @@ def options(opt): grp.add_option('-8', '--64bits', action = 'store_true', dest = 'ALLOW64', default = False, help = 'allow targetting 64-bit game dlls') - + grp.add_option('--enable-voicemgr', action = 'store_true', dest = 'VOICEMGR', default = False, help = 'enable voice manager') - + grp.add_option('--enable-goldsrc-support', action = 'store_true', dest = 'GOLDSRC', default = False, help = 'enable GoldSource engine support') - + opt.recurse('cl_dll dlls') - + opt.load('xcompile compiler_cxx compiler_c') if sys.platform == 'win32': opt.load('msvc msdev') @@ -45,7 +45,7 @@ def configure(conf): conf.env.PREFIX = '' conf.load('reconfigure') - + conf.start_msg('Build type') if conf.options.BUILD_TYPE == None: conf.end_msg('not set', color='RED') @@ -58,7 +58,7 @@ def configure(conf): # -march=native should not be used if conf.options.BUILD_TYPE == 'fast': Logs.warn('WARNING: \'fast\' build type should not be used in release builds') - + conf.env.VOICEMGR = conf.options.VOICEMGR conf.env.GOLDSRC = conf.options.GOLDSRC @@ -71,6 +71,11 @@ def configure(conf): conf.load('msvc msdev') conf.load('xcompile compiler_c compiler_cxx') + if conf.env.DEST_OS2 == 'android': + conf.options.ALLOW64 = True + conf.options.GOLDSRC = False + conf.env.SERVER_NAME = 'server' # can't be any other name, until specified + # print(conf.options.ALLOW64) conf.env.BIT32_MANDATORY = not conf.options.ALLOW64 @@ -122,24 +127,31 @@ def configure(conf): 'default': ['-O0'] } } - + conf.env.append_unique('CFLAGS', fwgslib.get_flags_by_type( compiler_c_cxx_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) conf.env.append_unique('CXXFLAGS', fwgslib.get_flags_by_type( compiler_c_cxx_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) conf.env.append_unique('LINKFLAGS', fwgslib.get_flags_by_type( linker_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) - + if conf.env.COMPILER_CC == 'msvc': conf.env.append_unique('DEFINES', ['_CRT_SECURE_NO_WARNINGS','_CRT_NONSTDC_NO_DEPRECATE']) else: conf.env.append_unique('DEFINES', ['stricmp=strcasecmp','strnicmp=strncasecmp','_LINUX','LINUX','_snprintf=snprintf','_vsnprintf=vsnprintf']) - cflags = ['-fvisibility=hidden','-Wno-write-strings','-fno-exceptions'] + cflags = ['-fvisibility=hidden','-Wno-write-strings','-fno-exceptions','-fno-rtti'] conf.env.append_unique('CFLAGS', cflags) conf.env.append_unique('CXXFLAGS', cflags + ['-Wno-invalid-offsetof']) - + + # strip lib from pattern + if conf.env.DEST_OS in ['linux', 'darwin'] and conf.env.DEST_OS2 not in ['android']: + if conf.env.cshlib_PATTERN.startswith('lib'): + conf.env.cshlib_PATTERN = conf.env.cshlib_PATTERN[3:] + if conf.env.cxxshlib_PATTERN.startswith('lib'): + conf.env.cxxshlib_PATTERN = conf.env.cxxshlib_PATTERN[3:] + conf.env.append_unique('DEFINES', 'CLIENT_WEAPONS') - + conf.recurse('cl_dll dlls') def build(bld): From ef9129b89e3d2f605b930feaf911d6d0e0a79466 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 28 May 2019 04:17:05 +0300 Subject: [PATCH 197/211] waflib: xcompile: update to latest version from Xash3D FWGS repository --- scripts/waflib/xcompile.py | 214 ++++++++++++++++++++++++++----------- wscript | 4 +- 2 files changed, 155 insertions(+), 63 deletions(-) diff --git a/scripts/waflib/xcompile.py b/scripts/waflib/xcompile.py index b72d87e4..c30ec2bf 100644 --- a/scripts/waflib/xcompile.py +++ b/scripts/waflib/xcompile.py @@ -12,6 +12,7 @@ # GNU General Public License for more details. from fwgslib import get_flags_by_compiler +from waflib import Logs import os import sys @@ -25,15 +26,68 @@ import sys # DEST_OS2 DEST_OS # 'android' 'linux' +# This class does support ONLY r10e and r19c NDK class Android: + ctx = None # waf context arch = None toolchain = None api = None toolchain_path = None ndk_home = None + ndk_rev = 0 is_hardfloat = False + clang = False + + def __init__(self, ctx, arch, toolchain, api): + self.ctx = ctx + for i in ['ANDROID_NDK_HOME', 'ANDROID_NDK']: + self.ndk_home = os.getenv(i) + if self.ndk_home != None: + break + + if not self.ndk_home: + conf.fatal('Set ANDROID_NDK_HOME environment variable pointing to the root of Android NDK!') + + # TODO: this were added at some point of NDK development + # but I don't know at which version + # r10e don't have it + source_prop = os.path.join(self.ndk_home, 'source.properties') + if os.path.exists(source_prop): + with open(source_prop) as ndk_props_file: + for line in ndk_props_file.readlines(): + tokens = line.split('=') + trimed_tokens = [token.strip() for token in tokens] + + if 'Pkg.Revision' in trimed_tokens: + self.ndk_rev = int(trimed_tokens[1].split('.')[0]) + else: + self.ndk_rev = 10 + + if self.ndk_rev not in [10, 19]: + ctx.fatal('Unknown NDK revision: {}'.format(self.ndk_rev)) + + self.arch = arch + if self.arch == 'armeabi-v7a-hard': + if self.ndk_rev <= 10: + self.arch = 'armeabi-v7a' # Only armeabi-v7a have hard float ABI + self.is_hardfloat = True + else: + raise Exception('NDK does not support hardfloat ABI') + + self.toolchain = toolchain + + if self.ndk_rev >= 19 or 'clang' in self.toolchain: + self.clang = True + + if self.is_arm64() or self.is_amd64() and self.api < 21: + Logs.warn('API level for 64-bit target automatically was set to 21') + self.api = 21 + elif self.ndk_rev >= 19 and self.api < 16: + Logs.warn('API level automatically was set to 16 due to NDK support') + self.api = 16 + else: self.api = api + self.toolchain_path = self.gen_toolchain_path() - # TODO: New Android NDK support? # TODO: Crystax support? # TODO: Support for everything else than linux-x86_64? # TODO: Determine if I actually need to implement listed above @@ -48,7 +102,13 @@ class Android: ''' Checks if selected architecture is **32-bit** or **64-bit** x86 ''' - return self.arch.startswith('x86') + return self.arch == 'x86' + + def is_amd64(self): + ''' + Checks if selected architecture is **64-bit** x86 + ''' + return self.arch == 'x86_64' def is_arm64(self): ''' @@ -60,66 +120,80 @@ class Android: ''' Checks if selected toolchain is Clang (TODO) ''' - return self.toolchain.startswith('clang') + return self.clang def is_hardfp(self): return self.is_hardfloat def gen_toolchain_path(self): path = 'toolchains' + + if sys.platform.startswith('linux'): + toolchain_host = 'linux' + elif sys.platform.startswith('darwin'): + toolchain_host = 'darwin' + elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): + toolchain_host = 'windows' + else: raise Exception('Unsupported by NDK host platform') + + toolchain_host += '-' + + # Assuming we are building on x86 + if sys.maxsize > 2**32: + toolchain_host += 'x86_64' + else: toolchain_host += 'x86' + if self.is_clang(): - raise Exception('Clang is not supported yet') - else: + if self.ndk_rev < 19: + raise Exception('Clang is not supported for this NDK') + + toolchain_folder = 'llvm' + if self.is_x86(): + triplet = 'i686-linux-android{}-'.format(self.api) + elif self.is_arm(): + triplet = 'armv7a-linux-androideabi{}-'.format(self.api) + else: + triplet = self.arch + '-linux-android{}-'.format(self.api) + else: + if self.is_x86() or self.is_amd64(): toolchain_folder = self.arch + '-' + self.toolchain elif self.is_arm(): toolchain_folder = 'arm-linux-androideabi-' + self.toolchain else: toolchain_folder = self.arch + '-linux-android-' + self.toolchain - if sys.platform.startswith('linux'): - toolchain_host = 'linux' - elif sys.platform.startswith('darwin'): - toolchain_host = 'darwin' - elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): - toolchain_host = 'windows' - else: raise Exception('Unsupported by NDK host platform') - - toolchain_host += '-' - - # Assuming we are building on x86 - if sys.maxsize > 2**32: - toolchain_host += 'x86_64' - else: toolchain_host += 'x86' - - if self.arch == 'x86': + if self.is_x86(): triplet = 'i686-linux-android-' elif self.is_arm(): triplet = 'arm-linux-androideabi-' else: triplet = self.arch + '-linux-android-' - return os.path.join(path, toolchain_folder, 'prebuilt', toolchain_host, 'bin', triplet) + return os.path.join(path, toolchain_folder, 'prebuilt', toolchain_host, 'bin', triplet) def cc(self): - return os.path.abspath(os.path.join(self.ndk_home, self.toolchain_path + 'gcc')) + return os.path.abspath(os.path.join(self.ndk_home, self.toolchain_path + ('clang' if self.is_clang() else 'gcc'))) def cxx(self): - return os.path.abspath(os.path.join(self.ndk_home, self.toolchain_path + 'g++')) + return os.path.abspath(os.path.join(self.ndk_home, self.toolchain_path + ('clang++' if self.is_clang() else 'g++'))) def system_stl(self): # TODO: proper STL support return os.path.abspath(os.path.join(self.ndk_home, 'sources', 'cxx-stl', 'system', 'include')) def sysroot(self): - arch = self.arch - if self.is_arm(): - arch = 'arm' - elif self.is_arm64(): - arch = 'arm64' - path = 'platforms/android-{0}/arch-{1}'.format(self.api, arch) + if self.ndk_rev >= 19: + return os.path.abspath(os.path.join(self.ndk_home, 'sysroot')) + else: + arch = self.arch + if self.is_arm(): + arch = 'arm' + elif self.is_arm64(): + arch = 'arm64' + path = 'platforms/android-{}/arch-{}'.format(self.api, arch) - return os.path.abspath(os.path.join(self.ndk_home, path)) + return os.path.abspath(os.path.join(self.ndk_home, path)) def cflags(self): cflags = ['--sysroot={0}'.format(self.sysroot()), '-DANDROID', '-D__ANDROID__'] @@ -127,11 +201,13 @@ class Android: if self.is_arm(): if self.arch == 'armeabi-v7a': # ARMv7 support - cflags += ['-mthumb', '-mfpu=neon', '-mcpu=cortex-a9', '-mvectorize-with-neon-quad', '-DHAVE_EFFICIENT_UNALIGNED_ACCESS', '-DVECTORIZE_SINCOS'] + cflags += ['-mthumb', '-mfpu=neon', '-mcpu=cortex-a9', '-DHAVE_EFFICIENT_UNALIGNED_ACCESS', '-DVECTORIZE_SINCOS'] + if not self.is_clang(): + cflags += [ '-mvectorize-with-neon-quad' ] if self.is_hardfloat: cflags += ['-D_NDK_MATH_NO_SOFTFP=1', '-mhard-float', '-mfloat-abi=hard', '-DLOAD_HARDFP', '-DSOFTFP_LINK'] else: - cflags += ['-mfloat-abi=softfp'] # Tegra 2 sucks + cflags += ['-mfloat-abi=softfp'] else: # ARMv5 support cflags += ['-march=armv5te', '-mtune=xscale', '-msoft-float'] @@ -139,27 +215,22 @@ class Android: cflags += ['-mtune=atom', '-march=atom', '-mssse3', '-mfpmath=sse', '-DVECTORIZE_SINCOS', '-DHAVE_EFFICIENT_UNALIGNED_ACCESS'] return cflags + # they go before object list + def linkflags(self): + linkflags = ['--sysroot={0}'.format(self.sysroot())] + return linkflags + def ldflags(self): - ldflags = ['--sysroot={0}'.format(self.sysroot())] + ldflags = ['-lgcc', '-no-canonical-prefixes'] if self.is_arm(): if self.arch == 'armeabi-v7a': - ldflags += ['-march=armv7-a', '-Wl,--fix-cortex-a8'] + ldflags += ['-march=armv7-a', '-Wl,--fix-cortex-a8', '-mthumb'] if self.is_hardfloat: - ldflags += ['-Wl,--no-warn-mismatch'] + ldflags += ['-Wl,--no-warn-mismatch', '-lm_hard'] else: ldflags += ['-march=armv5te'] return ldflags - def __init__(self, ndk_home, arch, toolchain, api): - self.ndk_home = ndk_home - self.arch = arch - if self.arch == 'armeabi-v7a-hard': - self.arch = 'armeabi-v7a' # Only armeabi-v7a have hard float ABI - self.is_hardfloat = True - self.toolchain = toolchain - self.api = api - self.toolchain_path = self.gen_toolchain_path() - def options(opt): android = opt.add_option_group('Android options') android.add_option('--android', action='store', dest='ANDROID_OPTS', default=None, @@ -167,14 +238,6 @@ def options(opt): def configure(conf): if conf.options.ANDROID_OPTS: - for i in ['ANDROID_NDK_HOME', 'ANDROID_NDK']: - android_ndk_path = os.getenv(i) - if android_ndk_path != None: - break - - if not android_ndk_path: - conf.fatal('Set ANDROID_NDK_HOME environment variable pointing to the root of Android NDK!') - values = conf.options.ANDROID_OPTS.split(',') if len(values) != 3: conf.fatal('Invalid --android paramater value!') @@ -182,28 +245,57 @@ def configure(conf): valid_archs = ['x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'armeabi-v7a-hard', 'aarch64', 'mipsel', 'mips64el'] if values[0] not in valid_archs: - conf.fatal('Unknown arch: {0}. Supported: {1}'.format(values[0], ', '.join(valid_archs))) + conf.fatal('Unknown arch: {}. Supported: {}'.format(values[0], ', '.join(valid_archs))) - android = Android(android_ndk_path, values[0], values[1], values[2]) + android = Android(conf, values[0], values[1], int(values[2])) + setattr(conf, 'android', android) conf.environ['CC'] = android.cc() conf.environ['CXX'] = android.cxx() conf.env.CFLAGS += android.cflags() conf.env.CXXFLAGS += android.cflags() - conf.env.LINKFLAGS += android.ldflags() + conf.env.LINKFLAGS += android.linkflags() + conf.env.LDFLAGS += android.ldflags() conf.env.HAVE_M = True if android.is_hardfp(): conf.env.LIB_M = ['m_hard'] else: conf.env.LIB_M = ['m'] - conf.env.PREFIX = '/lib/{0}'.format(android.arch) + conf.env.PREFIX = '/lib/{}'.format(android.arch) - conf.msg('Selected Android NDK', android_ndk_path) + conf.msg('Selected Android NDK', '{}, version: {}'.format(android.ndk_home, android.ndk_rev)) # no need to print C/C++ compiler, as it would be printed by compiler_c/cxx - conf.msg('... C/C++ flags', ' '.join(android.cflags()).replace(android_ndk_path, '$NDK')) - conf.msg('... linker flags', ' '.join(android.ldflags()).replace(android_ndk_path, '$NDK')) + conf.msg('... C/C++ flags', ' '.join(android.cflags()).replace(android.ndk_home, '$NDK')) + conf.msg('... link flags', ' '.join(android.linkflags()).replace(android.ndk_home, '$NDK')) + conf.msg('... ld flags', ' '.join(android.ldflags()).replace(android.ndk_home, '$NDK')) # conf.env.ANDROID_OPTS = android conf.env.DEST_OS2 = 'android' # else: # conf.load('compiler_c compiler_cxx') # Use host compiler :) + +def post_compiler_cxx_configure(conf): + if conf.options.ANDROID_OPTS: + if conf.android.ndk_rev >= 19: + conf.env.CXXFLAGS_cxxshlib += ['-static-libstdc++'] + conf.env.LDFLAGS_cxxshlib += ['-static-libstdc++'] + return + +def post_compiler_c_configure(conf): + return + +from waflib.Tools import compiler_cxx, compiler_c + +compiler_cxx_configure = getattr(compiler_cxx, 'configure') +compiler_c_configure = getattr(compiler_c, 'configure') + +def patch_compiler_cxx_configure(conf): + compiler_cxx_configure(conf) + post_compiler_cxx_configure(conf) + +def patch_compiler_c_configure(conf): + compiler_c_configure(conf) + post_compiler_c_configure(conf) + +setattr(compiler_cxx, 'configure', patch_compiler_cxx_configure) +setattr(compiler_c, 'configure', patch_compiler_c_configure) diff --git a/wscript b/wscript index 9a2060b7..97131abb 100644 --- a/wscript +++ b/wscript @@ -139,9 +139,9 @@ def configure(conf): conf.env.append_unique('DEFINES', ['_CRT_SECURE_NO_WARNINGS','_CRT_NONSTDC_NO_DEPRECATE']) else: conf.env.append_unique('DEFINES', ['stricmp=strcasecmp','strnicmp=strncasecmp','_LINUX','LINUX','_snprintf=snprintf','_vsnprintf=vsnprintf']) - cflags = ['-fvisibility=hidden','-Wno-write-strings','-fno-exceptions','-fno-rtti'] + cflags = ['-fvisibility=hidden','-Wno-write-strings'] conf.env.append_unique('CFLAGS', cflags) - conf.env.append_unique('CXXFLAGS', cflags + ['-Wno-invalid-offsetof']) + conf.env.append_unique('CXXFLAGS', cflags + ['-Wno-invalid-offsetof', '-fno-rtti', '-fno-exceptions']) # strip lib from pattern if conf.env.DEST_OS in ['linux', 'darwin'] and conf.env.DEST_OS2 not in ['android']: From 60bb207ff4eaa5d50c5090e40332587cd9ba8908 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Mon, 13 May 2019 01:08:25 +0300 Subject: [PATCH 198/211] Fix momentary_door sounds --- dlls/doors.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dlls/doors.cpp b/dlls/doors.cpp index c12cc3a0..085ee441 100644 --- a/dlls/doors.cpp +++ b/dlls/doors.cpp @@ -926,6 +926,7 @@ public: void Spawn( void ); void Precache( void ); void EXPORT MomentaryMoveDone( void ); + void EXPORT StopMoveSound( void ); void KeyValue( KeyValueData *pkvd ); void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); @@ -1117,7 +1118,15 @@ void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP } void CMomentaryDoor::MomentaryMoveDone( void ) +{ + SetThink(&CMomentaryDoor::StopMoveSound); + pev->nextthink = pev->ltime + 0.1; +} + +void CMomentaryDoor::StopMoveSound() { STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseMoving ) ); EMIT_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noiseArrived ), 1, ATTN_NORM ); + pev->nextthink = -1; + ResetThink(); } From 1f2f268173717215c27e626d6c301bf1026307f1 Mon Sep 17 00:00:00 2001 From: tyabus Date: Mon, 27 May 2019 18:07:17 +0300 Subject: [PATCH 199/211] Add deny noise for func_recharger and func_healthcharger, when activator's health/armor is full --- dlls/h_battery.cpp | 2 +- dlls/healthkit.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/h_battery.cpp b/dlls/h_battery.cpp index 976a5733..7b8182b3 100644 --- a/dlls/h_battery.cpp +++ b/dlls/h_battery.cpp @@ -116,7 +116,7 @@ void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use } // if the player doesn't have the suit, or there is no juice left, make the deny noise - if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) ) + if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( pActivator->pev->armorvalue == 100 ) ) { if( m_flSoundTime <= gpGlobals->time ) { diff --git a/dlls/healthkit.cpp b/dlls/healthkit.cpp index 99d53d35..cef99747 100644 --- a/dlls/healthkit.cpp +++ b/dlls/healthkit.cpp @@ -187,7 +187,7 @@ void CWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE u } // if the player doesn't have the suit, or there is no juice left, make the deny noise - if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) ) + if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( pActivator->pev->health == 100 ) ) { if( m_flSoundTime <= gpGlobals->time ) { From 873bacccebfbb5ba4bdc676c75f8b3e4d0e12969 Mon Sep 17 00:00:00 2001 From: tyabus Date: Wed, 29 May 2019 16:31:16 +0300 Subject: [PATCH 200/211] Replace magic numbers, Put changes under cvar --- dlls/game.cpp | 2 ++ dlls/game.h | 1 + dlls/h_battery.cpp | 4 +++- dlls/healthkit.cpp | 3 ++- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dlls/game.cpp b/dlls/game.cpp index 284e5a9d..03ee0dca 100644 --- a/dlls/game.cpp +++ b/dlls/game.cpp @@ -31,6 +31,7 @@ cvar_t friendlyfire = { "mp_friendlyfire","0", FCVAR_SERVER }; cvar_t falldamage = { "mp_falldamage","0", FCVAR_SERVER }; cvar_t weaponstay = { "mp_weaponstay","0", FCVAR_SERVER }; cvar_t selfgauss = { "mp_selfgauss", "1", FCVAR_SERVER }; +cvar_t chargerfix = { "mp_chargerfix", "0", FCVAR_SERVER }; cvar_t satchelfix = { "mp_satchelfix", "0", FCVAR_SERVER }; cvar_t forcerespawn = { "mp_forcerespawn","1", FCVAR_SERVER }; cvar_t flashlight = { "mp_flashlight","0", FCVAR_SERVER }; @@ -471,6 +472,7 @@ void GameDLLInit( void ) CVAR_REGISTER( &falldamage ); CVAR_REGISTER( &weaponstay ); CVAR_REGISTER( &selfgauss ); + CVAR_REGISTER( &chargerfix ); CVAR_REGISTER( &satchelfix ); CVAR_REGISTER( &forcerespawn ); CVAR_REGISTER( &flashlight ); diff --git a/dlls/game.h b/dlls/game.h index 0dc5ba87..7eb665c6 100644 --- a/dlls/game.h +++ b/dlls/game.h @@ -28,6 +28,7 @@ extern cvar_t friendlyfire; extern cvar_t falldamage; extern cvar_t weaponstay; extern cvar_t selfgauss; +extern cvar_t chargerfix; extern cvar_t satchelfix; extern cvar_t forcerespawn; extern cvar_t flashlight; diff --git a/dlls/h_battery.cpp b/dlls/h_battery.cpp index 7b8182b3..e4c00467 100644 --- a/dlls/h_battery.cpp +++ b/dlls/h_battery.cpp @@ -26,6 +26,8 @@ #include "saverestore.h" #include "skill.h" #include "gamerules.h" +#include "weapons.h" +#include "game.h" class CRecharge : public CBaseToggle { @@ -116,7 +118,7 @@ void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use } // if the player doesn't have the suit, or there is no juice left, make the deny noise - if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( pActivator->pev->armorvalue == 100 ) ) + if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( chargerfix.value ) && ( pActivator->pev->armorvalue == MAX_NORMAL_BATTERY ) ) { if( m_flSoundTime <= gpGlobals->time ) { diff --git a/dlls/healthkit.cpp b/dlls/healthkit.cpp index cef99747..0f8c521e 100644 --- a/dlls/healthkit.cpp +++ b/dlls/healthkit.cpp @@ -22,6 +22,7 @@ #include "player.h" #include "items.h" #include "gamerules.h" +#include "game.h" extern int gmsgItemPickup; @@ -187,7 +188,7 @@ void CWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE u } // if the player doesn't have the suit, or there is no juice left, make the deny noise - if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( pActivator->pev->health == 100 ) ) + if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( chargerfix.value ) && ( pActivator->pev->health >= pActivator->pev->max_health ) ) { if( m_flSoundTime <= gpGlobals->time ) { From 31b9b72bc9fb55b465735b14b51d7eba2f60b9d9 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 6 Jun 2019 03:37:08 +0300 Subject: [PATCH 201/211] waf: update to waf 2.0.17, rename waflib to waifulib, remove some modules, as they're now inside waf binary(see waifu project) --- cl_dll/wscript | 2 +- scripts/waflib/deps.py | 65 -- scripts/waflib/force_32bit.py | 56 -- scripts/waflib/fwgslib.py | 30 - scripts/waflib/msdev.py | 774 ----------------------- scripts/waflib/reconfigure.py | 47 -- scripts/{waflib => waifulib}/xcompile.py | 7 +- waf | 17 +- 8 files changed, 13 insertions(+), 985 deletions(-) delete mode 100644 scripts/waflib/deps.py delete mode 100644 scripts/waflib/force_32bit.py delete mode 100644 scripts/waflib/fwgslib.py delete mode 100644 scripts/waflib/msdev.py delete mode 100644 scripts/waflib/reconfigure.py rename scripts/{waflib => waifulib}/xcompile.py (98%) diff --git a/cl_dll/wscript b/cl_dll/wscript index a9b912e3..d0bd0951 100644 --- a/cl_dll/wscript +++ b/cl_dll/wscript @@ -21,7 +21,7 @@ def build(bld): 'dlls/hornetgun.cpp', 'dlls/mp5.cpp', 'dlls/python.cpp', 'dlls/rpg.cpp', 'dlls/satchel.cpp', 'dlls/shotgun.cpp', 'dlls/squeakgrenade.cpp', 'dlls/tripmine.cpp', 'dlls/glock.cpp' ]) - + source += bld.path.ant_glob(['hl/*.cpp']) source += [ 'ev_hldm.cpp', 'ammo.cpp', 'ammo_secondary.cpp', 'ammohistory.cpp', diff --git a/scripts/waflib/deps.py b/scripts/waflib/deps.py deleted file mode 100644 index f216515b..00000000 --- a/scripts/waflib/deps.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# Michel Mooij, michel.mooij7@gmail.com - -from waflib import Utils -from waflib import Errors - - -def get_deps(bld, target): - '''Returns a list of (nested) targets on which this target depends. - - :param bld: a *waf* build instance from the top level *wscript* - :type bld: waflib.Build.BuildContext - :param target: task name for which the dependencies should be returned - :type target: str - :returns: a list of task names on which the given target depends - ''' - try: - tgen = bld.get_tgen_by_name(target) - except Errors.WafError: - return [] - else: - uses = Utils.to_list(getattr(tgen, 'use', [])) - deps = uses[:] - for use in uses: - deps += get_deps(bld, use) - return list(set(deps)) - - -def get_tgens(bld, names): - '''Returns a list of task generators based on the given list of task - generator names. - - :param bld: a *waf* build instance from the top level *wscript* - :type bld: waflib.Build.BuildContext - :param names: list of task generator names - :type names: list of str - :returns: list of task generators - ''' - tgens=[] - for name in names: - try: - tgen = bld.get_tgen_by_name(name) - except Errors.WafError: - pass - else: - tgens.append(tgen) - return list(set(tgens)) - - -def get_targets(bld): - '''Returns a list of user specified build targets or None if no specific - build targets has been selected using the *--targets=* command line option. - - :param bld: a *waf* build instance from the top level *wscript*. - :type bld: waflib.Build.BuildContext - :returns: a list of user specified target names (using --targets=x,y,z) or None - ''' - if bld.targets == '': - return None - targets = bld.targets.split(',') - for target in targets: - targets += get_deps(bld, target) - return targets - diff --git a/scripts/waflib/force_32bit.py b/scripts/waflib/force_32bit.py deleted file mode 100644 index efec6b11..00000000 --- a/scripts/waflib/force_32bit.py +++ /dev/null @@ -1,56 +0,0 @@ -# encoding: utf-8 -# force_32bit.py -- force compiler to create 32-bit code -# Copyright (C) 2018 a1batross -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -from fwgslib import get_flags_by_compiler - -# Input: -# BIT32_MANDATORY(optional) -- fail if 32bit mode not available -# BIT32_ALLOW64(optional) -- ignore all checks, just set DEST_SIZEOF_VOID_P to 8 -# Output: -# DEST_SIZEOF_VOID_P -- an integer, equals sizeof(void*) on target - -def check_32bit(ctx, msg): - try: - ctx.check_cc( - fragment='''int main( void ) - { - int check[sizeof(void*) == 4 ? 1: -1]; - return 0; - }''', - msg = msg) - except ctx.errors.ConfigurationError: - return False - return True - -def configure(conf): - if getattr(conf.env, 'BIT32_ALLOW64'): - conf.env.DEST_SIZEOF_VOID_P = 8 - else: - if check_32bit(conf, 'Checking if \'{0}\' can target 32-bit'.format(conf.env.COMPILER_CC)): - conf.env.DEST_SIZEOF_VOID_P = 4 - else: - flags = ['-m32'] - # Think different. - if(conf.env.DEST_OS == 'darwin'): - flags = ['-arch', 'i386'] - env_stash = conf.env - conf.env.append_value('LINKFLAGS', flags) - conf.env.append_value('CFLAGS', flags) - conf.env.append_value('CXXFLAGS', flags) - if check_32bit(conf, '...trying with additional flags'): - conf.env.DEST_SIZEOF_VOID_P = 4 - else: - conf.env.DEST_SIZEOF_VOID_P = 8 - conf.env = env_stash - if getattr(conf.env, 'BIT32_MANDATORY') and conf.env.DEST_SIZEOF_VOID_P == 8: - conf.fatal('Compiler can\'t create 32-bit code!') diff --git a/scripts/waflib/fwgslib.py b/scripts/waflib/fwgslib.py deleted file mode 100644 index e7cdee0d..00000000 --- a/scripts/waflib/fwgslib.py +++ /dev/null @@ -1,30 +0,0 @@ -# encoding: utf-8 -# fwgslib.py -- utils for Waf build system by FWGS -# Copyright (C) 2018 a1batross -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -import os - -def get_flags_by_compiler(flags, compiler): - out = [] - if compiler in flags: - out += flags[compiler] - elif 'default' in flags: - out += flags['default'] - return out - -def get_flags_by_type(flags, type, compiler): - out = [] - if 'common' in flags: - out += get_flags_by_compiler(flags['common'], compiler) - if type in flags: - out += get_flags_by_compiler(flags[type], compiler) - return out diff --git a/scripts/waflib/msdev.py b/scripts/waflib/msdev.py deleted file mode 100644 index df6b2ca9..00000000 --- a/scripts/waflib/msdev.py +++ /dev/null @@ -1,774 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# Michel Mooij, michel.mooij7@gmail.com -# modified: Alibek Omarov, a1ba.omarov@gmail.com - -''' -Summary -------- -Exports and converts *waf* project data, for C/C++ programs, static- and shared -libraries, into **Microsoft Visual Studio**, also known as **msdev**, -project files (.vcproj) and solution (.sln) files. - -**Microsoft Visual Studio** is a mature and stable integrated development -environment for, amongst others, the C and C++ programming language. A free -version of this IDE, known as the *express* version can be obtained from Microsoft -at http://wwww.visualstudio.com. - -Description ------------ -When exporting *waf* project data, a single **Visual Studio** solution will be -exported in the top level directory of your *WAF* build environment. This -solution file will contain references to all exported **Visual Studio** -projects and will include dependencies between those projects and will have the -same name as APPNAME variable from the top level *wscript* file. - -For each single task generator (*waflib.TaskGenerator*), for instance a -*bld.program(...)* which has been defined within a *wscript* file somewhere in -the build environment, a single **Visual Studio** project file will be generated -in the same directory as where the task generator has been defined. -The name of this task generator will be used as name for the exported **Visual -Studio** project file. If for instance the name of the task generator is -*hello*, then a **Visual Studio** project file named *hello.vcproj* will be -exported. - -Example below presents an overview of an environment in which **Visual Studio** -files already have been exported:: - - . - ├── components - │ └── clib - │ ├── program - │ │ ├── cprogram.vcproj - │ │ └── wscript - │ ├── shared - │ │ ├── cshlib.vcproj - │ │ └── wscript - │ └── static - │ ├── cstlib.vcproj - │ └── wscript - │ - ├── waf.vcproj - ├── appname.sln - └── wscript - - -Projects will be exported such that they will use the same settings and -structure as has been defined for that build task within the *waf* build -environment as much as possible. Note that since cross compilation is not -really supported in this IDE, only the first environment encountered that -is targeted for **MS Windows** will be exported; i.e. an environment in -which:: - - bld.env.DEST_OS == 'win32' - -is true. - - -Please note that in contrast to a *normal* IDE setup the exported projects -will contain either a *debug* **or** a *release* build target but not both at -the same time. By doing so exported projects will always use the same settings -(e.g. compiler options, installation paths) as when building the same task in -the *waf* build environment from command line. - - -Usage ------ -**Visual Studio** project and workspace files can be exported using the *msdev* -command, as shown in the example below:: - - $ waf msdev - -When needed, exported **Visual Studio** project- and solution files can be -removed using the *clean* command, as shown in the example below:: - - $ waf msdev --clean - -Once exported simply open the *appname.sln* using **Visual Studio** -this will automatically open all exported projects as well. - -Tasks generators to be excluded can be marked with the *skipme* option -as shown below:: - - def build(bld): - bld.program(name='foo', src='foobar.c', msdev_skip=True) - -''' - -import os -import sys -import copy -import uuid -import shutil -import xml.etree.ElementTree as ElementTree -from xml.dom import minidom -from waflib import Utils, Logs, Errors, Context -from waflib.Build import BuildContext -# import waftools -# from waftools import deps -from deps import get_targets -from subproject import get_subproject_env - - -def options(opt): - '''Adds command line options to the *waf* build environment - - :param opt: Options context from the *waf* build environment. - :type opt: waflib.Options.OptionsContext - ''' - opt.add_option('--msdev', dest='msdev', default=False, action='store_true', help='select msdev for export/import actions') - opt.add_option('--clean', dest='clean', default=False, action='store_true', help='delete exported files') - - -def configure(conf): - '''Method that will be invoked by *waf* when configuring the build - environment. - - :param conf: Configuration context from the *waf* build environment. - :type conf: waflib.Configure.ConfigurationContext - ''' - pass - - -class MsDevContext(BuildContext): - '''export C/C++ tasks to MS Visual Studio projects and solutions.''' - cmd = 'msdev' - - def execute(self): - '''Will be invoked when issuing the *msdev* command.''' - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) - self.pre_build() - - for group in self.groups: - for tgen in group: - try: - f = tgen.post - except AttributeError: - pass - else: - f() - try: - self.get_tgen_by_name('') - except Exception: - pass - - self.msdev = True - if self.options.clean: - cleanup(self) - else: - export(self) - self.timer = Utils.Timer() - -def export(bld): - '''Exports all C and C++ task generators as **Visual Studio** projects - and creates a **Visual Studio** solution containing references to - those project. - - :param bld: a *waf* build instance from the top level *wscript*. - :type bld: waflib.Build.BuildContext - ''' - if not bld.options.msdev and not hasattr(bld, 'msdev'): - return - - Logs.pprint('RED', '''This tool is intended only to ease development for Windows-fags. -Don't use it for release builds, as it doesn't enables WinXP compatibility for now!''') - - solution = MsDevSolution(bld) - targets = get_targets(bld) - - saveenv = bld.env # root env - for tgen in bld.task_gen_cache_names.values(): - if targets and tgen.get_name() not in targets: - continue - if getattr(tgen, 'msdev_skipme', False): - continue - try: - bld.env = get_subproject_env(bld, tgen.path, True) - except IndexError: - bld.env = saveenv - if set(('c', 'cxx')) & set(getattr(tgen, 'features', [])): - project = MsDevProject(bld, tgen) - project.export() - - (name, fname, deps, pid) = project.get_metadata() - solution.add_project(name, fname, deps, pid) - - solution.export() - - -def cleanup(bld): - '''Removes all **Visual Studio** projects and workspaces from the - *waf* build environment. - - :param bld: a *waf* build instance from the top level *wscript*. - :type bld: waflib.Build.BuildContext - ''' - if not bld.options.msdev and not hasattr(bld, 'msdev'): - return - - targets = get_targets(bld) - saveenv = bld.env - - for tgen in bld.task_gen_cache_names.values(): - if targets and tgen.get_name() not in targets: - continue - if getattr(tgen, 'msdev_skipme', False): - continue - try: - bld.env = get_subproject_env(bld, tgen.path) - except IndexError: - bld.env = saveenv - if set(('c', 'cxx')) & set(getattr(tgen, 'features', [])): - project = MsDevProject(bld, tgen) - project.cleanup() - - solution = MsDevSolution(bld) - solution.cleanup() - - -class MsDev(object): - '''Abstract base class used for exporting *waf* project data to - **Visual Studio** projects and solutions. - - REMARK: - bld.objects() taks generators are treated as static libraries. - - :param bld: Build context as used in *wscript* files of your *waf* build - environment. - :type bld: waflib.Build.BuildContext - ''' - - PROGRAM = '1' - '''Identifier for projects containing an executable''' - - SHLIB = '2' - '''Identifier for projects containing a shared library''' - - STLIB = '4' - '''Identifier for projects containing a static library''' - - C = 'c' - '''Identifier for projects using C language''' - - CXX = 'cxx' - '''Identifier for projects using C++ language''' - - def __init__(self, bld): - self.bld = bld - - def export(self): - '''Exports a **Visual Studio** solution or project.''' - content = self.get_content() - if not content: - return - if self.xml_clean: - content = self.xml_clean(content) - - node = self.make_node() - if not node: - return - node.write(content) - Logs.pprint('YELLOW', 'exported: %s' % node.abspath()) - - def cleanup(self): - '''Deletes a **Visual Studio** solution or project file including - associated files (e.g. *.ncb*). - ''' - cwd = self.get_cwd() - for node in cwd.ant_glob('*.user'): - node.delete() - Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) - for node in cwd.ant_glob('*.ncb'): - node.delete() - Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) - for node in cwd.ant_glob('*.suo'): - node.delete() - Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) - for node in cwd.ant_glob('*.sln'): - node.delete() - Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) - node = self.find_node() - if node: - node.delete() - Logs.pprint('YELLOW', 'removed: %s' % node.abspath()) - - def get_cwd(self): - cwd = os.path.dirname(self.get_fname()) - if cwd == "": - cwd = "." - return self.bld.srcnode.find_node(cwd) - - def find_node(self): - name = self.get_fname() - if not name: - return None - return self.bld.srcnode.find_node(name) - - def make_node(self): - name = self.get_fname() - if not name: - return None - return self.bld.srcnode.make_node(name.lower()) - - def get_fname(self): - ''' Returns file name.''' - return None - - def get_content(self): - ''' Returns file content.''' - return None - - def xml_clean(self, content): - s = minidom.parseString(content).toprettyxml(indent="\t") - lines = [l for l in s.splitlines() if not l.isspace() and len(l)] - lines[0] = '' - return '\n'.join(lines) - - -class MsDevSolution(MsDev): - '''Class used for exporting *waf* project data to a **Visual Studio** - solution located in the lop level directory of the *waf* build - environment. - - :param bld: Build context as used in *wscript* files of your *waf* build - environment. - :type bld: waflib.Build.BuildContext - ''' - - def __init__(self, bld): - super(MsDevSolution, self).__init__(bld) - self.projects = {} - self.xml_clean = None - - def get_fname(self): - '''Returns the workspace's file name.''' - return '%s.sln' % getattr(Context.g_module, Context.APPNAME) - - def export(self): - '''Exports a **Visual Studio** solution.''' - dst = self.get_fname() - - s = MSDEV_SOLUTION - - with open(dst, 'w') as f: - for line in s[0:3]: - f.write(line) - for name, (fname, deps, pid) in self.projects.items(): - sid = str(uuid.uuid4()).upper() - f.write('Project("{%s}") = "%s", "%s", "{%s}"\n' % (sid, name, fname, pid)) - if len(deps): - f.write('\tProjectSection(ProjectDependencies) = postProject\n') - for d in deps: - try: - (_, _, pid) = self.projects[d] - except KeyError: - pass - else: - f.write('\t\t{%s} = {%s}\n' % (pid, pid)) - f.write('\tEndProjectSection\n') - f.write('EndProject\n') - for line in s[3:8]: - f.write(line) - for _, (_, _, pid) in self.projects.items(): - f.write('\t\t{%s}.Debug|Win32.ActiveCfg = Debug|Win32\n' % (pid)) - f.write('\t\t{%s}.Debug|Win32.Build.0 = Debug|Win32\n' % (pid)) - for line in s[8:]: - f.write(line) - Logs.pprint('YELLOW', 'exported: %s' % os.path.abspath(dst)) - - def add_project(self, name, fname, deps, pid): - '''Adds a project to the workspace. - - :param name: Name of the project. - :type name: str - :param fname: Complete path to the project file - :type fname: str - :param deps: List of names on which this project depends - :type deps: list of str - ''' - self.projects[name] = (fname, deps, pid) - - -class MsDevProject(MsDev): - '''Class used for exporting *waf* project data to **Visual Studio** - projects. - - :param bld: Build context as used in *wscript* files of your *waf* build - environment. - :type bld: waflib.Build.BuildContext - - :param gen: Task generator that contains all information of the task to be - converted and exported to the **Visual Studio** project. - :type gen: waflib.Task.TaskGen - ''' - - def __init__(self, bld, gen): - super(MsDevProject, self).__init__(bld) - self.gen = gen - self.id = str(uuid.uuid4()).upper() - self.type = self.get_type(gen) - self.language = self.get_language(gen) - self.buildpath = self.get_buildpath(bld, gen) - - def get_type(self, gen): - if set(('cprogram', 'cxxprogram')) & set(gen.features): - return MsDev.PROGRAM - elif set(('cshlib', 'cxxshlib')) & set(gen.features): - return MsDev.SHLIB - else: - return MsDev.STLIB - - def get_language(self, gen): - return MsDev.CXX if 'cxx' in gen.features else MsDev.C - - def get_buildpath(self, bld, gen): - pth = '%s/%s' % (bld.path.get_bld().path_from(gen.path), gen.path.relpath()) - return pth.replace('/', '\\') - - def get_fname(self): - '''Returns the project's file name.''' - return '%s/%s.vcproj' % (self.gen.path.relpath().replace('\\', '/'), self.gen.get_name()) - - def get_root(self): - '''Returns a document root, either from an existing file, or from template.''' - fname = self.get_fname() - if os.path.exists(fname): - tree = ElementTree.parse(fname) - root = tree.getroot() - else: - root = ElementTree.fromstring(MSDEV_PROJECT) - return root - - def get_content(self): - '''Returns the content of a project file.''' - root = self.get_root() - root.set('Name', self.gen.get_name()) - root.set('ProjectGUID', '{%s}' % self.id) - configurations = root.find('Configurations') - for configuration in configurations.iter('Configuration'): - configuration.set('ConfigurationType', '%s' % self.type) - configuration.set('OutputDirectory', '%s\\msdev' % self.buildpath) - configuration.set('IntermediateDirectory', '%s\\msdev' % self.buildpath) - for tool in configuration.iter('Tool'): - name = tool.get('Name') - if name == 'VCCLCompilerTool': - tool.set('PreprocessorDefinitions', '%s' % self.get_compiler_defines(self.gen)) - includes = [] - for include in self.get_compiler_includes(self.bld, self.gen): - includes.append('%s' % include) - tool.set('AdditionalIncludeDirectories', ';'.join(includes)) - if name == 'VCLinkerTool': - if self.type == MsDev.PROGRAM: - # Force Windows Subsystem - # TODO: this isn't enables Windows XP compatibility! - tool.set('SubSystem', '2') - self.update_link_deps(tool) - self.update_link_paths(tool) - files = root.find('Files') - self.update_includes(files) - self.update_sources(files) - return ElementTree.tostring(root) - - def update_includes(self, files): - '''Add include files.''' - includes = [] - for filtr in files.iter('Filter'): - if filtr.get('Name') == 'Header Files': - for include in filtr.iter('File'): - includes.append(include.get('RelativePath')) - break - if len(includes) == 0: - filtr = ElementTree.SubElement(files, 'Filter', attrib={'Name':'Header Files', 'Filter':'h;hpp;hxx;hm;inl;inc;xsd'}) - filtr.set('UniqueIdentifier', '{%s}' % str(uuid.uuid4()).upper()) - for include in self.get_include_files(self.bld, self.gen): - if include not in includes: - ElementTree.SubElement(filtr, 'File', attrib={'RelativePath':'%s' % include}) - - def update_sources(self, files): - '''Add source files.''' - sources = [] - for filtr in files.iter('Filter'): - if filtr.get('Name') == 'Source Files': - for source in filtr.iter('File'): - sources.append(source.get('RelativePath')) - break - if len(sources) == 0: - filtr = ElementTree.SubElement(files, 'Filter', attrib={'Name':'Source Files', 'Filter':'cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx'}) - filtr.set('UniqueIdentifier', '{%s}' % str(uuid.uuid4()).upper()) - for source in self.get_genlist(self.gen, 'source'): - if source not in sources: - ElementTree.SubElement(filtr, 'File', attrib={'RelativePath':'%s' % source}) - - def update_link_deps(self, tool): - '''Add libraries on which this project depends.''' - deps = tool.get('AdditionalDependencies') - - deps = [] # clean out deps everytime - - libs = self.get_link_libs(self.bld, self.gen) - for lib in libs: - dep = '%s.lib' % lib - if dep not in deps: - deps.append(dep) - if len(deps): - add_deps = " ".join(deps) # work around when converting to vcxproj by inserting spaces - tool.set('AdditionalDependencies', add_deps) - - def update_link_paths(self, tool): - deps = tool.get('AdditionalLibraryDirectories', '') - deps = [] - dirs = self.get_link_paths(self.bld, self.gen) - for dep in dirs: - if dep not in deps: - deps.append(dep) - if len(deps): - tool.set('AdditionalLibraryDirectories', ';'.join(deps)) - - def get_metadata(self): - '''Returns a tuple containing project information (name, file name and - dependencies). - ''' - name = self.gen.get_name() - fname = self.get_fname().replace('/', '\\') - deps = Utils.to_list(getattr(self.gen, 'use', [])) - return (name, fname, deps, self.id) - - def get_genlist(self, gen, name): - lst = Utils.to_list(getattr(gen, name, [])) - lst = [str(l.path_from(gen.path)) if hasattr(l, 'path_from') else l for l in lst] - return [l.replace('/', '\\') for l in lst] - - def get_compiler_options(self, bld, gen): - if self.language == MsDev.CXX: - flags = getattr(gen, 'cxxflags', []) + bld.env.CXXFLAGS - else: - flags = getattr(gen, 'cflags', []) + bld.env.CFLAGS - if self.type == MsDev.SHLIB: - if self.language == MsDev.CXX: - flags.extend(bld.env.CXXFLAGS_cxxshlib) - else: - flags.extend(bld.env.CFLAGS_cshlib) - return list(set(flags)) - - def get_compiler_includes(self, bld, gen): - includes = self.get_genlist(gen, 'includes') - for include in bld.env['INCLUDES']: - root = bld.path.abspath().replace('\\', '/') - pref = os.path.commonprefix([root, include]) - if pref == root: - node = bld.root.find_dir(include) - if node: - includes.append(node.path_from(gen.path).replace('/', '\\')) - - deps = Utils.to_list(getattr(gen, 'use', [])) - for dep in deps: - uselib_incs = bld.env['INCLUDES_%s' % dep] - for uselib_inc in uselib_incs: - root = bld.root.abspath().replace('\\', '/') - pref = os.path.commonprefix([root, uselib_inc]) - if pref == root: - node = bld.root.find_dir(uselib_inc) - if node: - inc = node.path_from(gen.path).replace('/', '\\') - includes.append(inc) - Logs.pprint('YELLOW', 'Added relative include: %s' % inc) - includes.append(uselib_inc) - return includes - - def get_compiler_defines(self, gen): - defines = self.get_genlist(gen, 'defines') + gen.bld.env.DEFINES - if 'win32' in sys.platform: - defines = [d.replace('"', '\\"') for d in defines] - defines = ';'.join(defines) - return defines - - def get_link_options(self, bld, gen): - flags = getattr(gen, 'linkflags', []) + bld.env.LINKFLAGS - if self.language == MsDev.CXX: - if self.type == MsDev.SHLIB: - flags.extend(bld.env.LINKFLAGS_cxxshlib) - else: - flags.extend(bld.env.LINKFLAGS_cshlib) - return list(set(flags)) - - def get_link_libs(self, bld, gen): - libs = Utils.to_list(getattr(gen, 'lib', [])) - deps = Utils.to_list(getattr(gen, 'use', [])) - for dep in deps: - try: - tgen = bld.get_tgen_by_name(dep) - except Errors.WafError: - uselib_libs = bld.env['LIB_%s' % dep] - for uselib_lib in uselib_libs: - libs.append(uselib_lib) - pass - else: - if self.type == MsDev.STLIB: - libs.append(dep) - return libs - - def get_link_paths(self, bld, gen): - dirs = [] - deps = Utils.to_list(getattr(gen, 'use', [])) - for dep in deps: - try: - tgen = bld.get_tgen_by_name(dep) - except Errors.WafError: - uselib_paths = bld.env['LIBPATH_%s' % dep] - for uselib_path in uselib_paths: - root = bld.root.abspath().replace('\\', '/') - pref = os.path.commonprefix([root, uselib_path]) - if pref == root: - node = bld.root.find_dir(uselib_path) - if node: - libpath = node.path_from(gen.path).replace('/', '\\') - dirs.append(libpath) - Logs.pprint('YELLOW', 'Added relative library path: %s' % libpath) - dirs.append(uselib_path) - pass - else: - if self.type in (MsDev.STLIB, MsDev.SHLIB): - directory = '%s\\msdev' % tgen.path.get_bld().path_from(gen.path) - if directory not in dirs: - dirs.append(directory.replace('/', '\\')) - elif self.type in (MsDev.PROGRAM): - for directory in tgen.lib_paths: - if directory not in dirs: - dirs.append(directory.replace('/', '\\')) - return dirs - - def get_include_files(self, bld, gen): - includes = [] - for include in self.get_genlist(gen, 'includes'): - node = gen.path.find_dir(include) - if node: - for header in node.ant_glob('*.h*'): - includes.append(header.path_from(gen.path).replace('/', '\\')) - - for include in bld.env['INCLUDES']: - root = bld.path.abspath().replace('\\', '/') - pref = os.path.commonprefix([root, include]) - if pref == root: - node = bld.root.find_dir(include) - if node: - for header in node.ant_glob('*.h*'): - includes.append(header.path_from(gen.path).replace('/', '\\')) - - return includes - - -MSDEV_PROJECT = \ -''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -''' - -MSDEV_SOLUTION = [ -'Microsoft Visual Studio Solution File, Format Version 8.00\n', -'# Visual Studio 2005\n', -'Global\n', - 'GlobalSection(SolutionConfigurationPlatforms) = preSolution\n', - 'Debug|Win32 = Debug|Win32\n', - 'EndGlobalSection\n', - 'GlobalSection(ProjectConfigurationPlatforms) = postSolution\n', - 'EndGlobalSection\n', - 'GlobalSection(SolutionProperties) = preSolution\n', - 'HideSolutionNode = FALSE\n', - 'EndGlobalSection\n', -'EndGlobal\n', -'\n'] diff --git a/scripts/waflib/reconfigure.py b/scripts/waflib/reconfigure.py deleted file mode 100644 index 333e64ac..00000000 --- a/scripts/waflib/reconfigure.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Copyright (c) 2019 mittorn - -''' -Reconfigure - -Store/load configuration user input - -Usage: - def options(opt): - opt.load('reconfigure') - - def configure(conf): - conf.load('reconfigure') - - ./waf configure --reconfigure -''' - -from waflib import Configure, Logs, Options, Utils, ConfigSet -import os - -import optparse -STORE_PATH = 'build/configuration.py' - -def options(opt): - opt.add_option('--rebuild-cache', dest='rebuild_cache', default=False, action='store_true', help='load previous configuration') - opt.add_option('--reconfigure', dest='reconfigure', default=False, action='store_true', help='load and update configuration') - -def configure(conf): - store_data = ConfigSet.ConfigSet() - options = vars(conf.options) - environ = conf.environ - if conf.options.reconfigure or conf.options.rebuild_cache: - store_data.load(STORE_PATH) - if conf.options.reconfigure: - for o in options: - if options[o]: store_data['OPTIONS'][o] = options[o] - store_data['ENVIRON'].update(environ) - store_data.store(STORE_PATH) - conf.environ = store_data['ENVIRON'] - conf.options = optparse.Values(store_data['OPTIONS']) - else: - store_data['OPTIONS'] = vars(conf.options) - store_data['ENVIRON'] = conf.environ - store_data.store(STORE_PATH) - \ No newline at end of file diff --git a/scripts/waflib/xcompile.py b/scripts/waifulib/xcompile.py similarity index 98% rename from scripts/waflib/xcompile.py rename to scripts/waifulib/xcompile.py index c30ec2bf..3244a95a 100644 --- a/scripts/waflib/xcompile.py +++ b/scripts/waifulib/xcompile.py @@ -11,7 +11,8 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -from fwgslib import get_flags_by_compiler +try: from fwgslib import get_flags_by_compiler +except: from waflib.extras.fwgslib import get_flags_by_compiler from waflib import Logs import os import sys @@ -76,8 +77,8 @@ class Android: self.toolchain = toolchain - if self.ndk_rev >= 19 or 'clang' in self.toolchain: - self.clang = True + if self.ndk_rev >= 19 or 'clang' in self.toolchain: + self.clang = True if self.is_arm64() or self.is_amd64() and self.api < 21: Logs.warn('API level for 64-bit target automatically was set to 21') diff --git a/waf b/waf index 7066d9f3..652bae2b 100755 --- a/waf +++ b/waf @@ -32,13 +32,13 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect -VERSION="2.0.15" -REVISION="ff6573b86ad5ff5d449c8852ad58b8bc" -GIT="02c9f814da0d3f3cd4c1a4f9c5e0c7ed7129bb19" +VERSION="2.0.17" +REVISION="0b58f6af6b52bcb6cae0b82df8107844" +GIT="31da55afb92d9865019eb5193e874d1ffb86c522" INSTALL='' -C1='#/' -C2='#,' -C3='#$' +C1='#9' +C2='#7' +C3='#/' cwd = os.getcwd() join = os.path.join @@ -160,11 +160,10 @@ wafdir = find_lib() sys.path.insert(0, wafdir) if __name__ == '__main__': - + sys.path.insert(0, 'scripts/waifulib') from waflib import Scripting Scripting.waf_entry_point(cwd, VERSION, wafdir) #==> -#BZh91AY&SYÑðR½TØÿÿÿ´Ðÿÿÿÿÿÿÿÿÿÿÿu  ƒ¬00Á˜0€(bÜ÷½¶w#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$#$¾Þ}:æÛS}pªr·°7b4×ÛC—ÛvÓµíÔºÚÑ67£R¤í¢D´äû‚×µ]µí×dÐXÔóÏ«ïœ wÜí½svÈä¡¥%½žÝÞ‚µ-µÐbîãÛ1Ö÷½ÁRß|ÎVO]EçºðYî•Ôûxr{ µ®ì÷½÷ßwß°<öøÞø×o¾Û^]¸¾æòÆ÷uÎ8#$ô#$#$ `#$xôz=<<”ÜP)ݳEµ:7w>Ž¯i=ÃUvi@F…:ÎÖÝÛ}:#$t÷°'`èä((m”(:0#/*”¢ŠvEJQ$#$Ð=®‘@•*®÷^¶{ë=½õÓop½%ÞÉŒ—{®în³)³§J•²u‰Jm×WÜõshõÔàw}¾×ZóÛ=·­ÊÞçZ÷½qRvÞöôööÍmï4}íŸfìÓ“Þ;)íõϽœÛËv¾÷Ñï}îûì«ÓU66ÕÙARBú`úzr®„¶Îö{̺ë7w{Ï]Ï\$¡ËwœŽÃÉ9´Ä¥Zwyø4#$J*’OCžºP½ÏO%4ÝãµÑuµ·n½†I>àwzÕñ÷nûŸ@dm….˜¥­­uÝ6¾1l·ÖQ°ùÝçx#$^íïP;xíö3w·žû{}uá_ö2`æ>ëhQkO¾÷x–›»jœkŸGD¥ž³Ìøûß^ZnÅ÷½{mz›¦ã;±÷¼Öé&Þ8»Ù§[eÞï¯>¼åô¥±E°h/®k¹×ßxå»2ìøL½³ÒòÂ…=í®KºÝ=·o¾)zÖΰ´OŸf½»³m¬Þìûc¯4Ùº>´÷·rÞÖç5VO^ìáìröðw·.œÕ½Þ¯n/`í\÷^w§]÷¼Ø}Ûàé\Ž¤ %Rгæ0d6ld¦Ù»«ì«t»Ûzó.3»6Põ81ÜÑ+®Ø¼ð÷²“k×f÷GBõž´Û¶åà#$ jÚ #$÷«—.®ó²‹Ž™Í{e´Û½ÎœŸlwÜa÷®›9HáÜ΂yÌ»e+ß}ÁÉæ÷nTÓê¹fÔçDA½¸õçu¯v<Û¾|w{{Û®›à2Z ¡ÛÜ°ö5լ̽Ñæª@÷²õ«Ò'¹òùö=ów书·»Ý½Ýݼw;HmôÙß{[ºçŧ¦Ç¹N7kœç …j[[(z/w¶ôeÛxïr0VØ6Uqã:^µkfðí­Öﶧ>}ˆ#$#½—#,USNÞ÷½©£Ó»£ƒ»nõ\ûºûTï2ïŽÕÓ«Üú|Í°«¯vfì/{}Ï»Åösn’ lR({y›zoZÛÒðÜ:­0,§}ã¼óÇÍö}o @hhR{3p#$UÇ•yÜï¾$ºl4#/¥žÎöKݸÒ¬œÛ…ÙÝÝœ în%U¶î›m7vƒwPU0Ø»iɪN»¶éîõÒû½í#/¯>êoL^Ó;=ÀMvNóºBczåÞž•z—rÎw,¿ÎuçÚë3š¹›…B˜ˆM^,Ñ2©Ù.e•) I„˜šlK]‹ ìcHÎ £».Ô2ø·,Œ¯MÍ#,’0ÄÅâà Š k{—¯ýË,?¹€nᯛۙ¢4Yòt\×ɯ&âvPR’(±b‚>ÿú”[”;žLVGµèØŠ)†Ú‹',•ö9’,Æ“ßÌl hlO5Rg„?³räúcG› G H!08˜q%òþ‡ÏýÛF[1Ý< •HuM¿Whc ½¾,A­ZÙdcÏnóºòŒs—EÜS+›t²Š¹·O;ˆ“cb}w_)­âÑ¢,ü}Õó¯Ê¯Ø·"™_"Û—!þ‹vÕã—7ÏÀˆKýó=í<™b#6ÌziÙÆÌk}žv×»Ùì÷U\¤Ú3ºåã×iÎãÂHˆÃz”eaÛÐÞ âk®WyÝÊ:W.d£.»¤‘Îd/µ­¼¼êÿbþ…Þ_DÕ(V)BŠ‘¦†wmŒºdâ2Õ‹}”R¢~—cj~§¦$2ðI.þŸ\¾*ú}ý^¡RzíE^© }x•³ù&¬ÂJ\ ﯳ8æŽÇCïβhÐìmð´SïŠytªùóöüjΫÙw¶×$Š Êh~-H¨¡F.%™‹Ž¶V[ÇCƒ#,hj¸2ÝFRrugjhÉÀM’_:ö]pfY™Xçüö¼ ÷ЇŔƒÊª)O‡_¶ýó¾¦rvîÖéɯB’"ÆÒ2…‘±•;“tÎAI£F…y&,¥:²Úl^”?ËókÓiĦ¢“áݸn#$(5£=VFmìÓ#1épJ.kšŠØ¼ïÙÞ½^D ¥Y*÷rÆ¢¿T·^îÇ­±dŠ#/ŒãFšâZ•T-ÅÔl›|ϺÞ1¨4–ûA™C…± xÞº±ÎÅÂ/”)½%E©Q:Ô–ãPåÌ Â#™­lÕŸ‚I„V~˳íënÊɱ_Wu_ÆèZI\÷²ðÑ$ZA`°Õ¶K ¤i(bÒC‹i¶¤ZÓ‰¡ëGƒ¶éE2„R]U¥"»wÕ¬ýUjxiK¿…e99eéÝeƒQ€§ŠÙ†¢œ8Ä1Š>ð± –…¶(ÑÝ¢4¶ÒÓV¾Ô¥ÝDÙè„_™„íÚ…i¶ŠÄêÃÍ–±ä¥ÑÒŠœ£Â©æüT{8:nÎ8º9ƒlXŽ‹ µË½ß2Ãq—ÙýP÷gzˆrõNüÀÆ5ÚC›¬0âMöT«¶³,3ÂË( Œb´fF”ß³ÜÌ}}í<ÓuÕÊdŸýfoÓðó€o¼ï3» ~é#åªi”"=í'”Ö¾ê£ô÷r³átpvWs'‡¯Wìш[hS“š÷Óo=R’\‰crF“MÏe‡×–ìƒ6q¸-H~I®ï2é°GÆ.]Ž¤AKƒ™S—<*J*¼(x{nrp¢rhû™B©úyß<|e‚D&˜gFÏÖë°µæø—_,q\—Í:¡g}–8ç–W<{*Cݶ…Æ q‡ÎöÒDcîH'›#,^óàÂÒZM¨´,>³¶ pÈÍRßi#v/P½}#Ç…œáÇ–tÊ©~#,-ÐÖ6¡õ«Løü¹í§Ö“:…^éKsYÃ.FÜðÖ=½åQäøªF‡õÌvG®ØcÀÑÖãz…U¨ÃÛ2‘ž>©[å¶Ò„˜p"Gû>—}©™nµÛ+jqðï×J]\t莑G×ÅɧðˆÖ“¯DezÀôQLŽ¢P¤Õ53ÃJºª‹:íƒtFóuƒvC•Ää#×Ç)'q¦”§E;yÎè™ù&?,¿žÕ3†1O}aNßçz<¶Ÿ'Ókðò¢Ûï9›õáH#>Œ)f©ÃaëR„wßlNðß@½)£¥­WÿtW–FnM´B8÷8»h¸×©Ûº†ä1žgY†Ùìé m±ÏËt÷4k˜yk¯žÖ›ï1×d$’DX |y…O^T¥=.bÀCý1“J4±é/±õ5¦O½TG§/Ho©ß¬¯eyï”×iUñ(¦/.ú¦¡ŒNñP:c²c¶œ%xr„@©#,§w9V;ÊÖÜkîÑz¬ÆÛ&Ç×®«,‚cȶ_Ê/‹4þ­ø;íœÍjvײ™ϳÃ!²¢*n“í“êïçï×[7åЉ*U“!VT­°¾Ö…›J+¹]zî§ÐÜe÷zºšÒ{®‹#,õ¹~- UKTWý–¢¤&|¯ü·_‹ø¼ëióü{¯RWÞÔWÞÃíKb"¤øÑVŠ#AEöT¦|Ùê'ãÛ›¥ªßJ Vä=,5úÙ•Ÿ[úùÏF(/«r²HŸÍ­µ}pÝoUèÔ5F»,¤ïUMD#,q=ð3ÙïÊõyyÎZÖ³KY1„û2ÖïHi™øB«ç|ÏpÐë°`7á5òœÕ>ÄêàY†¢sl«DùÖ%Î/‡ScmdývñüÑp3ä$Æs‹=d.©|d[Κwçt5`r`QöÑH¨¯çL ß³7:)x«1H²0¤çW~#,ZTÒ©ðÜÑŒùtuO³~y¾$_²Î抠Êsß¾4?¢-:ŸG»BF/£_A#,¯Æf½#,­ÛX)?)§ëq6œN¹ÚfAuôò“å]!¶P“ †ÕÁß2•À® ŒTSòe1¶¸µ987ðîËÚñ¤iši5¯,ühz‡ÐÀ¾Ú¤x3[…=;6¹‡ä—¶,/Z-€Š±%x^‘šDES#/‡‡ñJ m쪤<|À¤uNí+ê•ãE3’R“Jé{4}'k2C<"Tm¶³ìª¦ÞHóÛh5ÑêÈã¼ÔVm ð§g‹ˆ|ïK5x2#,ƒÒ¡À@¿cFì¥HˆÅé@R-¯¦9r¬èœlÿf´xð¨#/h6ÀêD´ðaK–R‚±7gFTaes×^¾o#,‘Ò÷àbì±):2É»ûÎû#T/\5‘~þõÇ$o…ÑEÿlC㉾=òUDõ"gÏPÞoÑÉü»2ü*mg}è–‰àøC›éwÏγŒk@‘‰¢RáɬE£[³±ê'ÿ®ázw\îó®wã™2‚ð;U°Ø¥”cO»8¹>¡ÖºUpCÄùòôìòؼž±D#/s º>~½xƒ5 #,¥ÛöÀ‡ŒëI ÛLj¡W.’¢ V­ãYPîz¡å½q‚écm\p­¾"š“¡¯¯ZºÊ[öÔþžTÊp¨CN¿‡JAQ’8dr*¾¤?½ÇWìdÛëB­;bŒ8õ¢[v>wNšÛ­bœ6¢<ìcy–—×áWŽhI—šZnÆ߯=÷ãt°\½ŽîÙÍûjƒ‹•ODóײôsîazL¼FžJÊkAì›÷ªE''Ni<·XôD}¡*¼Áq½Él‚Sòy ÙXoÎïG·o›Å‰líã^Aæ“g^²V¸³^¹©zÿ-}¸<(ñf`¨Åˆ³øtͽ‰UQ9c:ªLŠº]ó£áÙÈ?Vu*Ìe3âÔ#,¨‡Õ9!ø÷VìÔñÖ‹Gaš-íts¬CMd±#OzģС.|¨^6ŸåP¶u\dœ#ú4­\þŸve÷í&Pn‡Dä7Þ(ùb&¸ ÆF=ªDlÃø³}7€D#æÎ[_M±Ö1aújÖã¬K‡”8ª_ʧ5¿Ã8µ*5JæÑC7mDüÔ¤—œÌo|¹™ÇôîÌu© ܽ Pm´ÆÆ6½ì÷ì'}E~NçßlŸ¥ÐYŒ‚ØÏžü~š??¾€ÇZ;^õgšZ'ܬÆ'$´ç¯Àïç]Ÿ$îïàPºT7ìç rtƪÓ~ÐG]ŸÉ²cá¼Î¶¸¥åp«5)慎bkIQ~#,Z#/Êì–Íö£vÛiÎð7N ›hÄe hP"1b±ò&0b¦¶Öq‹⬠.…ìÔê”ÌUçˆri™a_™®‚|Ý:d³É‡h00Y½UDà’Ƭ…kUΩ‰…ÇEŽé)¡g½Ü‰ÛÉãhžª„ §²±ªÃÇš¯‡ª¥ÎôZçk=9uï—BŒL“£ò&3®k1µè‘s­_Å•äZD£b‰šõäí¨z Ú6ø{mû#˜ÊÑ°Þ9˜¤:4-×… Gæ#/±÷ãv™QƒI…°?ƒ¸Èóö*£ÄÖjŠ‰¯æL… <C*5š¨piS£1œZ$»¨zÝj”ˆÌÔ”)TJ(ËÇ׊\P**•R••5xíݹ¼N×"—W\u—ŸscV[Ù<áoœØlàux;—,âõ*5,<;’|¥I$¹$G4¡Õ{âS§#$bŸuðEÈ#$èýÚª„…{è~ãö€&€ ÕÑåÇqÞ`oÛõ‡éåXàËÑL ªÓÃýÿH—ô·7(ÅOO—J××"Þ7ÞÆ“š`GÌ'™{´«Ä2ŠžPrŠïº“\Ê6Ʊ…TçouDvóŒ©Ll›6ø'dЃgÙC8îMf8uŒÁ®[Â4íŒ95jü͵ÞŨã#z¤K_·NuÜ[}›$œîéøêL-U:b°£QÐj2H€jUñô²PŠWÚÈ°Q,-(Ä8¦D<‡²ÅœU¾…qÿ+«€>Ç°k¾`åaŒ16À3z.9IÑO;#yô#Bé —…U#$¿ô{í~­ mš#,qˆ¯m€|3dÆßÐÛuAò}î«ŸD]ç–¹¨úÍ»K(Çëê…c±sد*³ÊOyÇsÿÖ.•J1j¯Ôf^EŸ"+¾›m33ðz…Yb&ª"l½*ÖËïüùv@l7’¥‡ÉùX»ñhkãSq¼]sVŒéTBÞ»Áç8Ù”@uïÞ¯-À6Ôh]dô?&¹iu“ïÜ|Lh¬|FP‚ŽFGÛy$ÛËžL'AieþÕ6ŠGT—TÅgçœÙ•‚³J<Úo_«KÆÕÅÙ2Çj×¾”1VFuše`àã<ùwÕc£~|ÛMÃv^p,tB† ’Öj ìºåTaŤçDØW^OnÀš¾¹ðuâõ2cóÒŒÉñ÷ÛΈýD2ˇ)AÑûÅ Oq"!á0£yªP÷¶)s—j6ÓÅ.vxÒ"V n²zos³>É’[(—†S¹-Ö.6-sÊØá0ç.ò˜‰â0.ÅÌ( HH”Dy‘H–ŠM§ÍÚÚÜ.^|nkþÛ•ž´eÈ¿#,ö¶n‹|6ˆòY9t”!ŠLŠeµ¼!ŒtPvŽl…ê¼t5ü/ã«V%'D±[Æ"4¸`³Øúyl_=4žs°Ãu»úVîÝü,anÊgÍOøĬBèuþï@½Ún(Ô#{›7)ѹL üx6³,680ø[שÁ‡ö"ËÛLì|C±ëbcš?è-þë¥ +]©áZc¯~~ëàP§ÊdŠ@ˆÀú(ÿÝGW£+*tŽi?ß6s¡ß! 4Q‡:„‡öy¸í§7F$«Ý§û¦N¶cƒnA¡íª0 h›hš«;æ;àÐxõVpX#/€Ù} oåGMc*9i}È%|áÓ9—Ù¥¤K>é?ý€ÈŒŸ\tÕTE¥’$Sd’<]¶ò£˜y|"ŽIúÓ¬Dýã^›h‘n9·QáíÕçö{ê:}šÆÔD?¡#/!¿™W»×Kâ=å:ÿo_eý{&GûÈMÕD…°3µÏyû29€&Uš¸„ƒX‚HòNßGóìnÿk`úã‹¥Ýzï”$6#,®ˆwˆƒ@e\C1DDîÊ?ð$܈ÿbc}Äw33!ÏD‘o%«š$3ü\“ª"ML\îª"ˆ¤¡ô©ÞF#$ûæ®pš<©L±hŸW¨@yú£PˆŽ©ãÏi.²ïnîÊaôE»íë4âP[k¸ ô¿×k¤JÂ?)Ѻbþ¥úqÒ L#/XDÆ*^QŽøšDåç“é©3±A„„Ó|ËôÔÃ3T - YÙ éøâ“1€€Œyí·¯ÝsÊ°ýX¹Þ€\#Ku{cð÷J¢2—û~€ûâ€yAN`…L¢ºá×È÷|ñ ÕoÂÆ›‘5a3¬œµa{ |–/X: P‘ðûÕ°ò‚"õ¸E’ Wƒ¼Î@À\ø#^E¨ûÃÖ]5HõÏùésÆØ9ÍñÓ¬}/Œ­³!Ùý›òô`mSAêÍÎQö¥Ù»Aã¾?²è£é)ÿC³øfõÃ\ݲ»j8ô|üw[¶ê‡}úA÷ß¿’p¯§¡øÞßÃÔç$5µ¯AMà".Ï#$怳·§¦sìÜ¡ÈyfÃQk_‰U€x8ú/µÛ+"` õ{G_Îj•¨bP¢L…I$#,#€Ò,·Òc;ÊB•*è§üàûoõôgS³}2Õ‹Vç™ 8)²­?Þ¼/@¥ê*AÝ©Û-§ç•¿ `c, €J!ÝÈz‰:Èÿ¦]WG~€½ßÏŸî3ðó/ž‰û¸3·iå.Š©\6é ‚š™3»†£÷d²rŠ¹¡>’×µM7ý³Š )‹#É)WæïïÐ4: ,Pˆ½èÞ]òþÛ–…æå93O~6Fp“ù|8ü•µ3#$éì¹bíTƒÄ(œî#,K˜Iáì¬íAø0&½JlÖáôP^Ú²LMmŸhªc?|ñ‹ f]>.Òÿ>Š£åÑ¥¥‚KfxQÎ&'äÏþÛT‡QôAٜؔt퀱ZJÜû„YO‡iôÄžäi6,##,>]>Ü­zå´ŽPõ°@Û©9ÇX aa¡‡ühë%…¼‰z›oé4’ ÜºÙƪ¢ª©(NKoó²aè¸\á'×Æè\Žæ"õ#,òÜ3¸V?Æy%ˆHcHîM´?miŽÊR’:ù7¿½„õ{rk¬‡±÷‘¢#,qÈî•!¤dæ­>«ÖiÀý#/k៦vxýG<ÿNÿyÏ×°üßÄ“œ!dIËf´O•ÉáæDu–¿Ö=Ú¤ô4ÃFÉB ¬ý’¯óXЉÉ1NñèmÎ)¾ ƒ^«-Z ÙybA¤šìL3¾¾øÿ·|†£k†‰­*©¦t#,ĵF¥<Áª¯œ7¿)øSz]ù‡‰`uÀð›­E{|QäIå)²!u‘P™ØøFAˆºùo«ýp›fzo•ºˆÝ#/=0ú¼=ÍBûUÓVAÄìÙ3ÀÄ·±ß´vš'úxßÖýbI8÷ùlSXß½Y% q߸n©ÇA#°ëì_óúç¸o«ëýC±Ä¯aI4ˆjsð®!ÑQ¿-)¶-ÓòMé#,gABPOeú‰Èw¨þÕ¥†Úú›7ÍÌ å¤É *Ý0ƒÜþ³pç’Œsǘ7NÈFaתÍb(VÇc4LŠ/…„ï½tú|æ™é 2&ˆBžÑ…5Â6‡…ܦ2,,»¹Ç|زØR¢"ÈQˆæY…ÅÐA¥+Ž˜:Ö4Ž{Ïæ µ{ñ}ÚÕ6)­ÓJN`a!箽^Y›#/`&BI~™¹ËÏSjÊßEäßãü?Î#$Ƭ&²‡= !iÛʃyéëÉôþUÄùÿ¦…½ª.ÑÄ7^Eàx:¸ ¦z£:#$yDJ+š@ª   Æ±   °ùì&òˆk7O…)Ç€tFÖ×›B“±ØÑðÁ…Ï.‡ª^Ñ!ÅtãQ~‹fÁbƒ÷-ªÒIpJ[¦”.¹Qf–(L£Ñ_ 'bŽËƒ;ÀâOC;Õ_¦ä+œS%£T¤ ì5 ôœuI˜Uîš‹írZaå â*šÂÔhð¬De¢ç#â€ëÍt@ŠSa@¢…¤!42š¢‚„i,÷c+&œí#/ØÉh„L¢3´9³›©9’«¦ç؃UšciK,TÒšŠ¥ÛÝpýtt'çš‹áë:TPýQ£ÃîÏC3ª(ÒÖíá#,PllàèÄ;f2,âIÕ,Ñ؇F]0æÁ¡ÈÌ\åê¦å­…bPõYˆbŸ¿W8RíÊ›É*:dõ|{a,t¯[žXÝ¢)HHâ•ŽÎãòobŽžEPSJ5‘{Å Lê0Y»Eûæ4Qi| ôL¯nG[ªO8«,›}YE“Þ^×·cØqt¹³xH0«¿Ó°H™E• ›îãVú,Áµè´Wºtõ¬æ>…ÆfiX#$ÅsÞû áÓÐôÖãí^'ߧñÖÉC6S?4Æ7˜L´„€œ@Âj•¥aÓcllfH‰-LíwwZxìŒÆ"4st‹šRA@X-£µùkO6„Ö«¦óÓãÂóíæûñœ¾WÒrø¼ÖP °¦F2¡E• Ú¦*°¦0iDëøkÏ‹lÃq21ƒŽ0Äb#$ó:ÆN »rœH÷óÅeÞ¡»bIM)²˜¡ÜÝ Þ7†ÁO•F’ŠNÒOõI:,v;iï®÷v|ò í­«ë©V©vOZÃ#,¾ƒ±‡l ¢Ù \m_mònnÔ¼MQ!ùÜ.ÕioÇžh¸`áPP¦E ß8Uã&B®¨)à†ò"àdÄ`P #/×'xy¾¼á­#,#/S  ;¤,)ä|ÓñçÚ/)eˆ„C&u¦…ä‡Hc©•[}$ÚÕ9Ú¨Þ°¡k«K¤f¨;OÏ#$ìwÜ t>”¶>ûa…˜c2f¼ûójδcáV‘ŒôfÍðÐ<¼÷Ýlˆæ–6ÿÅ’¦,h!xQ¢ðÏK¾‘4&r\áfØëf)h¨niŠl™„­ãC•ÌÁZ6ÁmÔ±õ4 £cQ#,D4Ô:ÜhÆŠ4 0ú-Gñd@ñ˜#$†ŠÒ奉c‹6PºËÈ@˜‘ ë¿â"l^~wS/Ã1ÇmtrÇ-ñ[sF*OÓW¦-_q^{öÛcLŠ1bhÊ &Q4d¶ "†XTMPÄVǨê¥ '‰X£UŠ d""À§›c¥kå:{õ9mŽ pjög²È)~ÝlÀ¯ŒçàûáÏÖDÓ¡G嫶°52ðœ4›DSu#M©;´2@Ô 6ýÖùAÒ·}lïlºAD=8+_#/vIWLDz#$á®á9;'JI%]-¢à~ÍV’§éœ1N#,Ï¿…g/!­‚kT”AEH”Y-¶;Î$mŸ%Û±ƒÒ1,íûÇoØ·þ;0ðÆ鸘!áÆ°uyQZ·(b>6(µ¢=‰bÁ-žãýùzï@Ðâ”ysüúI|ѺÜò¶âµ"RDÕTÖÈT?²er¡Œ†öJFâ¹VìÆçÜû—À¼èœ‘sûý²[0J´6˜È†(Äq7“´š²"²#,t¦jb¡‘aTÒ0Y% ‹2h°†„à:ÈØ6²R(ÇH¢Ž y’*Iº†;û®…ÀMH†Ò+J†ÉvÒ#/)$Õ¤o.Ø…)ÚŠ"0Ñ¥bÈèQ„Ѹ&bÄÌ´¤±Ä:Ûƒ¯C@ìF5j#™†‰&Ć!‹L .Ì7—ëõñ{?O0ãBHÅ6OKD³Ò#,c!1š†4„LÏ·:×:VùÅ1¤w.#/WÒ<¥Ùž#—ŽÉ¶nqX‘ú»£¿ÎPâ6kŒ™_K•ÆÎEêRiüœ©DxÄrÓ‘LÃ4þDxÕ2ŒOÜõåc;›Gz ;ŒŠYu–•Ü×!­¡`·X®Ëá¼»Ö`ï>xúsé Ç p#fâ‘ ›Œz܈ñ×¢¿#ˆ#,Ê]C“·k–Þ£Ììó³ðâz™)ac·#$ÜTy’¶E”c °Xw$R@‘9¦Ïa¹C¢Ò{ŧBûãõëºL˜ì ƒO2HL³âœÙ‘vâB6l%?Óvó~ ý+êëg@÷9)ÐþJ(m#$Æ(†‘#/úg%°9®—RŠ•qTé‚‘¹¡"uQh¦4©#/Ñs£pµ¦cdä\PÀZÚæ1/üGؼ¶÷eø#$còíÛîš!æHaC?âݶåÉ•i"1E#/̈ÈA¦ü¼¥}xUoä.vaÄ!ð{eQ¸˜:¤ã'ò– ÷Ö§Cú#/7³är¾©îʼnøã߀TØéÌD$/…,¶ÌWŸ®?ÙóøÈó‘UŒOózíx8ívõìí×XøåCÐÓ­–oef…'ÕhK:–º(‚ó6 bZþJU1¶‹&të3ŠXAdX‰b±%2µÒɹ·Mh¶å¶é¶šb‘Z,ÄB0Æ2;Kd;Ø*t´;y–HM(dµ÷æ¤ëÀºfmj$ªjüÝìßMa룧óŒà“VSÛó#/‡°ö°ž9ÀûP€o£‘o¶¶Ù¸{ù‡ð‡*ñĶý¡¿7Û ²s¯º ºÏ‘òòsoG<0Ò0èRìÆJ5Óth,šŒþK¿nÁûÇߧGGZ 6¨žr–‘É=ÚYݾŽA/Â<9oÏá¼iá¹ýx:€äcú¼Âÿ>~ÙÛjÕµe…¿ÞcIê†Ü#,Au½bæGÿnaKì«$¾3ð?º¼Ñ-Çã-ðé[¶å+³)“Êàû=u3¾Á¾ïg!éÑ'Ñ.¸Ýlw{6"a*l hÒºˆ%ÁT„s*”`Af ŒtüqŒ ƒîø}_ðáØ;gC·§Ð0iùÉG…syéUäÎ)u”Û¯£Š¶ µ%mË b?gõõþ„#$Ž±CÙÿ¨0¾åjÆ5&¯ŸëýÙø€&šj¡$#/IÞG¯mЮŒ9>àTxaò'~ÍýayÉñ)ÅÈŽOâŽTÄXT(¶#=NÖ‚)›RY4Iˆ ÙRÄ¢üN3F›~òôvݨ£X5RŠh‚T IÿTKg_ÔÆuÛÇÜmׇgöCû„^›<á´Û"”¯Þ¿>)@PéÙ,'P£h€1(p‚ÏÂû.elE)’¨ ” )%*A<êî…ìMzq¯Ã—ïÐú?t¬\¢Z59<¦¥ DCçÓñþ¾§ÃOº²Ž‰˜†‘dF@tDj)"sœ¿Ê–~tš%‘‚ï“’ôþú ¨Ú#/Þ¥\Cmé$mo’ÔXŠ!våQUL„Pñ„OÑ‚1ö`|eæ³ÊŽÄë*Ω”Æ `FÅ (i_ºñôKHÕ+ýŠàà»Â¸2/ñdµä–ôµ`úc,¿¼ýÔþf¬X¾Xãüí.ƒ¦.!JÔ›Í]KÛ¿ûgáãpú% þHý/ß³‰»öñúaepz8xó.'#$ùEê¡B‘C«¡h#/Ví->Ÿºõ«½#,#,”ó¤=”Ý$‡ƒ]VÛGq˜_®æKQ#/ƒÑãžÿ¶¹<_š>(¶T(`£ ò\šoXdQP‰¨—Õ¯8dÆ]@ôKþ`Êß‹Â|â2~oSczKÒBm·êŠ}²ÐM&s*ðJOë¦h!0ÁVê(Ÿ)#$Ã7éý»¸h ýV)9t ù‘¾hqö{ÿ;_Ýèú~'é·òý­û^!îïú¾¯¬WÛÔ¾nI•=‡žÐå´õhçc+`ûæ?ÊïMKÿÛª[;:n6¥ÈX×oÓóŠi·»ïn »Î·,®wøkòÇ|~fÙHÚïÝ v#,5·“…t°äíýÐHÝ^1jIÂU@ã¦4õ};.H-Q;`ÇuçÛz—ÈÍâ‹J_Û‰V–B5¿ƒ€6´€àw_“@ó/‰ „E1ã«ó¦2™vïïøÛ‰ó™w>š?á×}Ê ‡Eú=.Ê6q“ïÇ>iw×…!Uð`á1˜·"Ót©o"Gæ#øQbr#óŽÁâ>Ò)ûÌ÷æ3êXá þ54(ÿ®˜4ô}”ùÿþ?´Ñ÷ž&¥Rå<ŸÏŸ‘À³¿9#,†5Šl¾ÌoÙß߀5'k,HZS)†·BãES°‰9ü;…Ïé륾'ЀÛü÷Óyfœn:aäΔŒ&SÉTØT”z¨šçešª™«0m$(pRqSÔÙi_ǵD„þ{*õò#,yÔ! 4òWáÊò ,ÈW•”'aOë£ïa¦ß¡¿Dű\NÔ¿zE7¾˜4¼P~õOׄ4™MÜóÕþÿó³í ñ°ïõÚy_¾¼'¾ªyÑÆÔ’b°žý~iˆÓ4јŠÂCcëʼ¿±BïUWÀ%Ç3ÕæØÏ)ŠŽcæ< ëRÀ`Gÿ_×C¿;_ŠÊÜý²¶ý¾Î ¼œ0½gçš™‚7CÏñìUÊR(Sàt” C 7P¤ HÑQUG°”N|Oo“ïÇÓ¯ol~ê3²4mŸ½JÝÉPq®0²X‰P´Bˆ5,¤ÞˆsR\!ñHG"¾y}ÆydZ¯˜‘½×(š›!õzÌé˜Í]]žÞúÿ§WÃÉõñ§¯êúœ}fÍÜýpUAïõt{ŽŸ]2Ô›>²Ë+Ç ¾¾ÆÎ~›X+×n‘§Ñ1¤¥µÑ~w.Zìíw±‘eïò/“Öfý·YWçfŽß»»Xݳä—-ÖZò½ñ¿"¢ZªöþÞü9»¥ÃÌ|{—£Œ›á|(ã­Á‰¿f~C±Û¢¾•iMýäZ:Ý«õnñáî×ÝêÑŸœÚ/ôeÍžŸòéø8îÓeÁEÂÀ2wgŽ§×ªzyü-˜ñŸE˜à<ÃN„—ëOgõ—É~Dr ¹$ƒä·ð~^ÝêèÇš’žÓeüÃêzoÇåûÞ9)²BZd9Ç£¥“çºÙCuÜëe;7Å´ãÖö½öcs'U'Ÿ‹æÙ,£mƒë€ËW¸;«Ù«ó›]ç$å‡?õ±Œ5Uµý¤zŸNm›tÆë_Aª;žÿ&ËÂÚx#«wF´.ÙwKWªZ|äè‘chæýZ=íˆ7ßm¶k¥×uÈÛ‚·™ê)HkïÎÊÌKͧ‹¦6i¢5#$íۤѯO‘x˜ä?b.–TÌýï1¯îþTç§ÙÆxòÕ'qôóqÇm¾^Øy·ðñ;µ“t±ÞïAözøJíW_ÝIïäØîÙ¡¡åPàˆ²VNî=+#,üiiÑë²]:š¥$Hqðê“ÓÉ%b$h_BÃOüaŽîÿ‡»[â9•šú)Öþîý>Q‹³ŽµwàñÃë °eãéê^ÿÀÏäôúG¹Ù0æÄg²úN#¼Ã‰Ü)¬gdFûcoºQUõW~6WíÑæÕ}:_äÔ-«a%ojú%¥}Wìdúã¤0?w wiGâºoú…æ_qµ@eh¡èƘø}rpÅunÆø÷C„彽äG*}ÞißèÛnQËø¨‘JüõN|Wìú[O ñ‹›Y»ôv'Ÿúü!,¾K?-:¶8B§ŸàÝKºßMݘv45ü€I/ûŒ½ò|†«àËÕÌ8ü½¿~p úh? Ñ^8•Ä(ëÃÍñ¯çÀt°Ù¦Kî[Gѯƒ¾‡ÏaÏÐæÎ7L˜J­,•ù]ó3¾\$Ø'8*,>–¯šUÿÁ¡¿ðÏB8a¡‘S™@#Ã0<ŽæÛê³ßíþu³³ì´síÏøŸÞ~Ÿ¨ýÇýnÓÝ£enæ‚d)ØÿòÏÙê¯u¶ÿB£Ó®¯÷„T…|_N£Â^vÉ¥Ûçoõg•ðÿ‘û¿¾,?pÊ%{ŒP‹5GŸö|¬¼Ãò:^Ëù»¤R[739 Ôiˆ_7™ d?/œ@ üÖ(´#$¥‹LRÓuèw3ÿ_Ù«AÑ÷zÂáÍO‘‡Ç_éø[Í-Óò}>ÎÌû„¿`±™µ÷õŽÛ±ñž§ê;¿Q—ðp"TŸN­ZV¿ÍªþA© ¯B'/Ô½È;Š#,=v8#Éßòϯ«÷ë¸aùû}ÃÞ>ñÄuFþo(ü‚…ËpêmŸ¢g¾çZ³öéÝDAþkõSøf“”zÏbgÐ>íåù~ì)ÕnŸ²¹¸iúøµnýÞËþ‹Á`ÛêN7GÛ›†Ùª=«péÕçù×Ó÷qÒŸ8ýÚ…›ù¼|´ˆ(ü5|z9nâÀ~ßÐ}©jw'›ˆåÍ#$ŽUh…Y_+ØÀSùHlgíàÓ÷!P„ÿDDñzíÄ&Ôi¢P$7ÿBqæaž4íþ=ý]ëÄ]·Ÿ§ùÈóîÐX¯ên.Ä=ü—G3¿|÷ÖdÉ~Ãå´óM}€7ôþ8YBAÜ<ÞHSàª1Ó‡„Å÷}»ß}8õó$u?|F¶ =ò¢žÝ÷›`2ßkDøÜ›êiû,³/¾¦»N±Úl–’é;ROÇ`È9ûÖïói‹àpY#,‘+!9%vJÆuÐSÑ4¯F<4θÞ=îåò\^ìóÂ7sñuÈT6Õ*DG[Kë¶8=H_ÃŒÒØQ2åG]ËÁØpöLÎ’À‡PA/#鄵µ6þ\4íóÏOÓì Àgsý›ÿX¿ßݦ@ì&ƒ½Ý, q±ÒÛƒï#," ËÁË0k¾T­(ŠáÎx™8Ï£¹ö#/Ó¢|c)¶øD¾Öæ6ï{çæµ—–Î"‰ÊçFîå®VSaclb^b„V¦?º{^nñß]_z‹èý:ÍI—BxóÉÌû#/z¢æd;iÊ·­uƒj¢B·Y7KAìHH!$ì²Ï”+©fàIü=³Ü’³L5GF Êõ?ó#,üúÇg¾ÑaǤQ=º<Û¥lŠínë)WÌÕ/ç#/Ÿ]a'JN<äs½N±EG˜t$ßôO±×ÈaŠ(ëÓ¤#/ߪÍ<ú;m•õÕ_ìì;q¹Ëõýí*G.×pÝQ«~©Ð´O>dÉ™ýåï–öl7·ÅÎÓò}\CÉdÃÉèBõ>I'òñÖÚØyÏ'yÿ–ÕÐãG•ý¼½Lÿ£§4Ûw+ý7x¬µ;RIÛµô¿>«úŸ;¤÷F/ulu³|¯ Ë£õº¶zñÂNòÿ7êöÐhö Ãx#$£˜#,8MzâÂ*I+ÏËiý{¦*?¿÷²U)ϘÈ/«…ø‡TAì’žQóü}ceëd#$?—4v^Ó 㬠U¼º3Ÿúþ”QG¥—õ,ûÜ?ÎZŒÌ¹‘µ[r²Á¨9G…?7F5¨0Ò¨6Ø©A ©EJ$ݱ!¡Ìn,$U¥–‚Éd.›?Í¥ÜY #/Í]ܦ¬Ë3"{pcÕ¤v)lv5‚Ec#,2J`B#,YCCt!I± ÕŠØ"²¸äca=Øj›0XÛIFɪ“O³ºaFf#$äfUI1KBz±Z8dÚu‰ü¿eî·£¾D&s˜Î‚PP}?·¤~+ÖS<%º¬ ñf¿ÒZ¨9+¨¶õêr© Ãc ‘F6“,# D‹¬¿êøoý÷¹ü?ª~«Fœ#¯#±E4D dˆ‘ÑÒ¬ÅÛBÒoPc Ø°©J¢L†­Abm6Ì-$•H ÿŠªP´Y¶ÏÞt~} ”ãoÇ/§ÍË2)ÏðMö ýøvˤß{#‡N4¾ œ-gÖl³L±€œçj·]uåËuž•ãŸÏ]tåî®­_»ÃÙ°KÎ=*¶~ŸÑéÎã¬cûº:9µïüãÉÞ'Švþ_Î÷ÛŸV³)åã î±lwÛ~ŸIŒ\ʶUd×vVÿ¦{#˜ßÃ\3 hî¨p°£ §Ü‚ˆô‰$:ùË®¨ügÉû?%ûu{´êöw”KP‚¿páÅÀ#,@&ª¦ß—ƒ€¶Ó«ÙÎ)ß 8oèëÎ8/ "N¿ßWƒ‘ÅÎs=Êé9¬ - <ý6¿—õëÂaSZ–êwËû›äüz5ùö;uñÕwiø"nÊÏÝ?ÇO|ŲY0¿º/´-þ!ˆëô«ŠGèéÁç­ëŠv‡ù<ùÛš3kÀÅnB‘mZ$VÒ†AÉXÅ)×%<¬Ñ#, cT8(–˜‚ÝÝ2[šI‚DdE•+k†”aRCt³ªTôäQj#,±´@ŒR±BÀdQØZáa++)YlÿFŒ#ƒÆUZ¹ÍÚŒ‚–©Z¢Ê…¢Ø„`£$éÒMæîx3#/F5Û”MÈ ©‚”`ÈB#,ÌF–Ì&ÄáÚë9µtÙ) lcQ#,£–dL0ã0¬éTZCâÓ¸èè²–×3‚HZ7Ï„KkA#$ekü.³«X#,<éD³‰:7³YhlbbÉeC…N"G«…Dt„Òdý­¢Ö–#/¹‘Tä"Pgj*ˆÂ®´ÊŒp#®²R1Œlž€b¹Ñø%W<¸ø!U†$‚’IsJCÙõC‹I4&é½’ôAŒô»/¾¨Ê^³¸a/øÜβ߼ÈÔŠ#/Åíç#/[hä ±S'›ûÔ? t"°ù_ôZ®Â¿xöéèÕ#/ýå¿aÙ­¨õ)ÿozð™Ó£Ë}ÓüÚŸ®»»š)ž3»0óXõ…ï¹~røütB&Ȉ‰Ó£Ì½s×N-ìË]†~[~=.Âk,µ9ÄÞÏÇò}No#ü*Ôõ@W±Ê ½s’ ‘•ü#/wA#$_ ð†${‡Û¯šjGCv›*8¦ÄWßé.eÒ ª’IfUUk{T~h$whM 9,HÙbzxwˆ øG?W÷Î\Ÿ@t¿/Šó‡àÑì7¾ÇðT‰n«urñÚˆšÉ$P(?ª‹u<â!ÜC½¹ð/õO¯æå|}o¶ê )Ù²gF=¥YÈ€*@*ŠA“ ™)‡}C’"³%÷TÅWsžI6‰ ~áZôëÑóqã ,^¹vçÌ"6 õuJ߇ÂÑ*¥ØP¬þMeTWùªÛF+,¥!FäEˆj%ý,VÀ'ûtÞm¢^[ÊŠŠB‚YQYCFF¶Ïl¿¯ÑÃÍgËÖ:ÿ#H-uí;wû~ßæÓòÉ ùÖÖ]¡€ªEˆÁÏf¹°ôL‘Ìs(²ýh­¾óA1³†#CÐá#ipkvé½¢šÁp3¦ª ð̱„A'š•šcÕ®ú¨« Á­A‘Š¼‘ƒX<Á™†ZEF L¢µWÐô=Z^%ëÀˆÄ×Õ&D=ÓxŒÇ‘À­«G:ó¬Ã”‚X,ãmµ‰îš  èrhŒ5`£yTîeLzDm,ݹÁ²#/¬ÙWÀ2ä²ÄÍZ¨¬ÛÕ§XCZ­¸ÆÛ…‘2SS¦¢f†¤ÅB(„6ZB„Rd˜– -£w-¬™9¤N½XkYX6ÝÕРÈv¦êÀ\†Ql›iB¨ãÕ?‡ù´hÐwG|ÃZËÍ*¬VkR¥B§‹†@ncJ{d­¿ ¢¡8Fñ™ßž #dƒ§“|üyû¹?›öuêP‚ ‹zîÝÍÌø¸Cwp˧Ê>øÅÍ5‘£Í!âA˜hcŘÓd/‹öÙò2›˜pÃñ#/ Ô#/ò÷?ü:9¦ƒ¤¸~Žäq¹Bߎt¢zxîG¿CPxû>£ðÏ#,<Ú½Wô§H'¤Ð@ípZ3=@>“XñäDe–AbŒX°´ª©øÒªˆ4ãñ»ÃìYˆˆÔŽ‘qq…áÃJ1¤J>©ôi`ªÉ.HŽ)FD‰©„8ÌøXÕoI¤TëšÃãÒ4IéÝæw±‹jÃÓ×G¤Ózt(qPGcÈE{ž/F°4¤´RéhƒD%„j64(¶ÝÌFç6®•U¢œBn3éýŸ®ŽØÌD:çTÒ‘I·c…Ñù‚D†CñÕ¿ýø¼þÞ»öû|GOïæåáéÇ|ÝzEÙjò “éÄ~?ÏþŸÓÏo¿µEÆóJ|˜Aº|fϺM‹–• ÈÜ[ª1ÑÚ@ûŒô¼f›Ò ÏŠŽ{µÌX¥×WÅî½æéË“i†9БZa Aæ ´Ž¶ãouQ”¡]VAü²–R7x26ˆ¶<ª¢‘¨6Óˆ®Ç!#/^Í BÑL8PÉÓV®g‹&CÅ”93Ä»‹GÁŒ¢Ë#/‚²kÉL¨3H/˜! #$PõDŒ¥J)¦ (ºs.`v[È¿c!‹›%Mƒ\ÑG™#,êPèó|¶Òðàšˆ;Y$ÈÝ•CFP›° LÉ4' ˜dDMXés‹ðTuZ¨WâÀÉš2ÒŒGËZŒÔŒdmw:™C”È·¸ŽØ¬#,B”#ȤË$cÊd%Rj×~ÐÏg~–‘nÔùzebB‡ˆŒtÎ"Ç2úå© ^&AÕÓ‹$'wÖöÄ¡/àî¶4Û}Myi÷4e1ls³§n,-ø.$’C,ruÆ6•žš#Ô‹Þî#,Kqªë¾h´„.ŽÎÜ…Ï9½"$ïnîÐCj qŒz±µZ$Â-àLd"mZ®GÜÏp.›gÊh#i™£^ÞxÑ{æ5ÓlfÁØÑHÞKš³“£ ˆÒƒÒ9Öi6!bÅ>UAß5W¶¬ÍíÃ[mþ&Ò}ÆœÄسV‚ƒb©Ç´Å›‡/ºîˆËîm±š¨2áBaµÇI¶v7…¶¹:^V1´iÃf†gd"3]ä(ØHeØØ0V âþ$D¬?•†Üq·œ¸ØC²IçgÚˆêŒVù³¶ã8m˜bÜöpó€¢Ó„Ð0­#,ï)ÖçÜŽ›4ÊêìoÄé…m!& &HHc½·–,¡|úçkÎíëÖï«È\´¦¿-wj]CKpùGYŒúf’Iiš’HÐ\;3¥cØñÃwå]‚'u´Ç ƒˆàÉoÉmˆˆ0C¹¨än*6”¢Þ-ó‹dÛ¶µÒ¹Q„’ƒ[#,Á¢<ž#/:26#,Š^W\m;ÐëÈQ¶ÔuvwD“y‰d­Ü*78Ø(æòÙÝ6øìŠ]qq¬ûè5‹#,À€Ûk[írã£åÒ+V;B'F)ºêèã9““;6TÊZ¹f±0Ljš¥Ó¦ÌNq˜²pÆȬ2Ìœ˜Ö…M‡#7ÕÉ';d%„¹¹­ÖîاPÆ#,Ž]¶ØÉËH'’mjM0ˆ0Úy›Æ_g¸åcbkË ÕoÓ:Ù¦å­ úŸ¡‡K4]µHè·Þzýþ˜ËÞ±I”I×*J¼C”îK$x˜í;¿M¥µ9`Ùkz: ÈÃÝ rqB1’ª7מm[^úJÿ׸ȓ‰ÈŒlI'V>Y?S#/kn¸ëšžÊæäýx¹­ö]x¸Ù¨[¼Ë&'&ÿÉuÂòu…œ¹RM|an‰¸ê!Ô¥•“ÄAl©·K¾;Æ–°´‘¼)ÁF§P6ø¤,½¬-®eß4ð¡“:R(½³#,TVÊDèú„Á ’`Mß›¢‹?ÜémÓ£ºJ÷Ï¥I¦hi¦ÁoµîXcOËÍtžòÂXä†ýk‡¾Üw‹ëš ~a²ÒÅ7iœa\±}:®³®«KiØ!>̇¡rÎÜâ°ñ©lš¿ëq÷”D>®g<¼™¬FAѤØM,ãsÚ ¢AÓ5ÏIYº·åÀºåG8A¬ê1‹&…røÃïn•$›ÑM†]†pÕÙ4ίEy ÕÒͲó1êi„º+‘›~øK¥¸[Ýûs–†—E>iP܈x]#/aF.™LÍÐiÓÏ@òθ-¶ŽŠ²2ï%½&¤„š`;]SBtÑÅÔb0TX«ïuwöW›nï!7û_c|¥õaǘ{³= θÅ"^yyXàV´ÙM¶µ†«`”Æ3ëÊ„ÿ댘£¨ûõNæ¦tgn0†QÁ°0¢¨$‹ÞìÛô-FñàtùTŽ?צ²v=ã)ûÍ.Ö”3¶ë™E3H¨œdQ*Ç žäÄ·ÔgÕWêÇõýç鉆®µ“ƒÔž_ïÌ/ÄÓÜ&‘!EU<â‚ÌF)¤A]…ºÿbZã€x}ÆWR6¨X¯F8x“ž^Høé«SÅ'Óäs·¨àOOèÂ0>_]ê(ˆ³Ú·ÇÛÞZW(Ý‹Ž¯3讕ɰ>cáµÙ¯#$σ-Þx úŸç1­$¼I2ÄÞ‡˜&†µwTR.‚ö¨°ʃ„—È0›FB뙌01Ú2ϧÕñü¬Kž2ïÇø/€¦Xù” £,Ëdå ƒÌ’À8O-0ÂþüN¯ïײÌûÎA‘߇ðÞáA`£`#$,;¤#ÂÕ!z[x0¥°nÚƂʸËRV¡Ëi@Áœ9»`ÐÆÀ%•Ã¦¹Hˆ·+;ˆ’ º úײ#qIö@OoØ9Úyos&ñBqÊ^L}æµTþ£ÀusùÅÛ/K§Ú?L,‘r²m8=õInm˜§OlÈR•P÷ŸŽ³þ×êþ‰lg[%^õßþîóÎpÎßI;ƒ³?“ºX‘é©Þö!2f*Ÿ)×Ù”?#,ã<#,‘JJ·d²àŒ¹r £i‚U‡ð%·6¶L[2;BÑZ–#/9b]­8ð3ŠÏcÝÇÊûK>»º…&Iˆ—ƒ,\ÀÈ›|jÌÅg}'ðHÕ[*Ãcº¨wj¾’R©!S&ÊË'D¬G¬\'›caOnµätÜ8,^À9ï’dþ¢®§—VÛy2»¯¸“ÌXnèí¿m¦tGIáRÄN4e‘·“‹fôÿ6õ¨nÅšðú(>BêÞšNíÑœú©(rÜtq•ä¢¯¬/v2‰¸A”"H9Ä•á2I©½0¬».:"‰7È÷ô}Ó¼šö¦N tß>Hhp2vB‡TáæÂúÔ)@Åԙɣ>³âºó:Ýü¬Ý© n’9/FÞ¤nÅ‹ýBÚ|£¬ã»L_AäPÓSO.Ã5)ϲ¢¹l„¯Vº-˜—^¯ŒùÔ:Û½vÐ$N™ü;1(ê2Ó#, Çhr¶‡iÅA1ÎF™ý•Î3[ËüÈ|¿ŸL™ñcšÈ+YQ_#`#,9àùYP³õ‘ÄElͽ¼<Í°|øŽËC£˜“–Â;‚Y†âºžè üÊmôöjìºè‡´óµ´Iòó,¡ã­-ñÕõ×E+#/S«NÔ§Ä~P;¤ñ]çVKè³óP;ñÃÉ!Vº¾huZ·†I¾ÚËÞÇ[oŠgFç“iÊÚŸ³YÌÔîå×#/Ô䎋¦_+ŽƒéktCú¸Õ.Øy3Œ‹eÆÊ:/âçY©ü‹é]#,t¦ÂÅXɈp)>”^Ÿ¤–fļޅ3ºt½}v²OŸow=D0 €ȃ՚5¦]彑ÝÇŽÝÈj߶)yoÏ…µÝ nDt2un6c+j/› ›M”Õ}“¬é9ã¯û„¨÷’´×>yÓå[œ¶”Poªµ¯Q¥"4¬#,Ó{K7aêhJÜ«„,Ûh\-!…õ¹4܉#/Æ;®Œ/繟ͦê ÓsT»f«ùW#/­/á9=jÑ´S½e˜‹EØàö¹ÑæÌB#$ÈX͵º9­hªâ¢ch(±üïGGc×~N…2ˆ§’ ‹¦\Ølz†Q‹ÿ·ÏjJÍ¡²Ž >zÛ ö‰ÍÎʶä©ÛÂû]Þ`y?%ad׸ª¾í7X¦ÿ]~p6œ áLqi1Þdì2r¸Øû&ùÂØyGEVf©câ’»ž8ŽV8úý5לÿfíæQ¹îVKeœøq¶£ ¥‘{ßuˆì{ÃœfÕ„WšR¹nŽÇÖúÜù%èmvá³ËW`§nã”e’B{ =ûŽä†BKʽËsãÓ.\°LÔr…ùN ^ã`°h­±1¶¡‹Kƒ&È:r5¶bÛà¥héZúò=#/£g#/¶‡ôÜòëÖùýÚÕæëÖ©å%2£²Õ<ªE#ž$­0ü[„ús¿]9Û^¤D;8bùY ¦÷h€ЄBáµl¿;%X]+#v¾šýI1¯•´±+n†Ÿ^¼iÄ‹¢ÍM<Öõ^©u\]ÚñÆû­Ž«A4ªI…¬]×ØÀ«…”x‹®ÎÁ%Ö¶/“Ä ­YÝ/§&¸ãY†;õñ;r™ç¯¯Ã¹“u™ã²š^ouéÉØŸ.úŒžìqfyÓ`ý£kŸsò!“ÁG«Â÷!Áuè«kÏQmSRÏ…[¡Ðy@ýP–¥ÙIËȔݶ.Œr™/zØCŠ“ÔNmÝ•/£I—od'÷¬/aC+fP·RìÆÀÔ"x’¥ÐQ±õ×®)t–hUÔƒÊw¨ {öþG×J:g=#,Û%†×xÛ®&idòyäõ‡ºóaµÐ«q*húX燫gäÆ7Ý)‰Ô5Ä­ÎsÂónˆ%¢”ž2v]‡Þ6ÆÐÛþÛ+™Þ#/–~G¼2)¦…•–LÈgzÿi‹¨%C#$Ž»“l¢/òJ×h7›»˜i;œ†zÄ›y6͹å8‡(Û#/>,˜ißïq®'Øö÷MïÆ~´^³ŸÃ'·Þ`â©“O§8Þæìx2,­Ší¤® ÕAUÕ`37”Ñ0¤`ósì¹ï6¸VÜ粎•«,üóqt²¥ö«¯s¢öXKAedíµò9)™ZjÑXlÖÝ‘„ÿ(ƒ[XnÜŸ÷®g¯ßõÓÂ\ñ˜6x6¸©@N8M0Õª"¢“I,vdc¯Z%U^7–ùÑ’ÜN¸¸L“#*åK%+Y9‡“},}ö ¥ax«aãzß6D7Æm-üT‹PH†‚ÙÏL„’ÚUñ¥Cå··+]´ij=¬•n×uÚµs¦XAÒHë›ç-« ß«óËß÷ÿp½ÖQn·sœêY̱±ê ÆÕ N–dGNóêâÔrÂ:”áNÕ1ž}ž)ÇWÙǾ±©38z†%~×rýw–›ÙÄ¢3×™™L?ßÁÊâ¼ð/õàÔ,èH†Éà]lZËãKÝMeÁÏ”lŸ”Dˆ²»ÌÝ4S\gÍ?®ÝgÞïË™Ðeûäð»SÖ³Û{›¦óR:b˜máÒ!4¡}oV}u†Êõ¢ÃMíð{UÇ”j¥úAiz‰¥*·‡uÑE‡¡o#/lçÃø’ÿ7¯©ë©8¾N$×õ²\4_“›ºB–ÆQSb²KƒÅðT—‹¬sã²þ˜5ðË™æ(H\‰7°Q¥1Q¢¢ÑWÎÃÞ§ws•}2os Êßu<°1×ô\ o¶1‚¡2õq¿f©3¶u-IDlÛ7Ñ ršA“I°’ÄSC™Áh\÷ÎXKSRªa%‡.á±ë&<'k’è+Ç0­¸¼?OcVq1þäçÏèýCÍ¥¯tXÊB"IC°g¯øwj¾r˜BWzâÎm^ljÓ8D”#­êÝÖêb-êóË>“ZL©_ƒœ“=ÌcÙ –”/P(P9ß]ÇÊ 2$È@ÑèhÚžÁ9"1ÎÌó„L)èè~’ò @+bª^í@^2].\}ý¯–±%c£S\iÓ%Áíqw]ZËùÁìî]‰Y!#/U qCð“tkQ,7J÷–¤„ÃÆ ­5gô>¤6(„(ÜtæâvBñ'Í잌»¹×LrðÐì:oùyð¶·lMå“\M²÷_ÈøB×MÊŠ%,ÆòJ8åèËt‘£NX#/S£zº3fY…Rïš4«¯÷V‘¬|oé‹õËýÙyÄ ]£x•fM9×%”—\U×{šGÑCƒ±œ-9ÔD:ú¶"Ü-«ðpbC˜-,psŸ‘Ôx¾0’Ël§Ðí5œ”‘¨êÕfKeŽ¨Ûwò^bn6}³3ˆÍSnQ¼ÁÄm w[Æcª<ʘÝt:kgå¶Ç9m.¾OÆw7™íÚŽh*ÂfEÄKýQ=h.w6•tÍý›¾šoôà~1ˆßÊÜ4=ä6êI‚Ä8·ñÃ}'¢sÛnn†1–‡ÌLÅgã*t|cÝW#/fÞ%-ê9“Ú+ùyÒ;;ô‹•Ÿ4Õøê ^JºMg¼Ý»\=¡¾ËßÎ[×ã’/ËÕ¸FµÒqå5ÌÓZ:ad*”u™ãÚÛ¿Eôƒ•<3‘ëŽ6$¶åñ¼¦tcQ\\?ò”Ÿ¾*QU„º–é#bR-I¶MŒVѶ®¸3õæ N$KDBˆ^täÍÅ‹ÆÇŒyLÂúfõíɯ·„ŸÊ‡Gcï8vœÉ:ª¤Y#"„X(1F²ÐMS¯2õ]:›–r:L'Lž¿?‘ˆñNÕ|[9vZ?jy³2»0Gnùò‡È.F!QáQxï][Ç3kÑÁuÛ_ˆ7pFròOïaoãèdý?Xö:)걸±ÕR&Ä—wJSbíiK88¯#$ï?’œoú70þ-“ì?›~Ûvˆ—çe,ÐÐ-=å–$>xÉÄ‘?WèTÐþµÅ¦œUM ¾,†OLÙ#,rt,ý¢Œ;A)ý[ÙÄîKN¥¢½@ *«2Þ(ƒF°ëõý‹÷i÷þ$«™à¸•hAºlK×:²ts²„½~×eœ}›¢ã(í ù¿c;šÑP9=F£&È^ã.Ž`ꈇ–2P³7hÙÿC¼®Õ%×á9æ¶ÞÃ<¸4%­¾ýÉØ€j£#/#/dY#,~ÊœÐ膨­ûSðB{)LW@@ÛõUµ@¨t2¥åj '«U(×ј”­gæ¨ñdS,ñÒ°éš“Å”¹u$À†É„AÉ5 â‘'1(´,Δv‘½´K².¿òˆc#$×úyjîØbìs±a?|¡×Þ?ìÍÓ}c••n~”V:–íB{Ú AÕ&Þ~Jôwˆ†=¦šîaGZ$p4°‰¦¸—±#ßcK–½ðÒš•ðíã“š‰=œ(“Wnê:£¦¦V,VUv#,íTY@‚òJ, ´“ y)¤ã\†èT¾¦Û¿oL|ï÷È,è¼¾7,::¡·çî¥G‚“ðÖèÞOýÓ[?’Dp; F„-¤ð¾ôù§P΀±|6%2(/ÜIñôùc잸íZŠ§ª¤ˆw‡ùËy‘áyü#o2P„!D7‰ØC›ôÿ=в…ß®¦™­®™Õ¬>µI=eJP(Z•U5/ØÜîwŒÛˆ£rj)æÞôüôk/wBò#$ùª¦`1…$ sÛ½õX“ãÒê´ÉÇ1¶ÿI”5™Ä=Ãi¤S1­kRÞáA*u&lÂ]Ó­QuŒdv 4›b@Ê8ÂE.©¸Š;bœrËõùŸ¼Ù÷à º×˜ñ:`(#/ „;{#$.uš…;!]tnÈ¿V­Úöìª6hô›j"Äßó(exÂL LùqáÅñøc‰¢ ù¾n¦åDD­…låÒïÈ#/€„PI¸pë·éwLÜmîÄëšÎ{~"(v3¿ñ¨e›!ÑìýªÔ2¾´@¨T:õi’kŒ†~ ‘oÃL²£ïŸ.N7–%LçO~/÷MÉþv‡f‘0ÔRdãmÚø|7¬yOGÇ3}¨î&t|Lú\Õœš²AES­PÁIÉ4J^m£˜)@ã3õãßP®"ûöÝÓŠWW@U=E…¸ÂϧÙ4Ðì…¥Ñ^ûŸ[¯?«^]TšÕ†q‚cå×Óyë³Gwéã×A˜Áàyå*q'#/žÎê—ÙAå#?ö³¬&ô—ÕñLÝ’ HM»#\Ëâ¦BÕ{Xñ~~qj0$áϤ<%8M¹+U¼çŽ§Z@YC¤rŅц¢`’†eR 1)sMãS—Þòg¤Gw“Ï,Ý-¤øFô~><@ynrC(kîÚáyŸ!¤c7¤ƒ³Íò ÎÈÛÈ)Ò5c1bOÓsîWCjóÍ)€àËÔ –¹#$b‰ @¶Á0›½ ~EW.ǬÞoŠMÿã¡$ˆD£ÍŠMÈ·»m¡ó<!98>ÕLfžÐi#w¤‚¤‚Þ<ÝçBË“öýÑ´õÃLtÒï·K-˜V q9EwS4džÿ §=Ý'Pý iÃë‘s-îã8ñÓã%`ì”ôßKâ®6-ÍÃ|ǹº†#çÀÜ “ËéË@ýŽO’ì픞²‰QæÑ{ƒƒôsÞåÛ#,qÛ…CÄß°·¨ŠOó.6¿¼y楘qB[ì_§¦Ô|Ngõ£~Mqâož‹þN\æL퀑`wdÃ@à±0#/.p…¢Peäiv ÷á;õÏI¡ã afÑšÜ×£ôj岂†U/.G“(>žåçG¾ÎÈnØ=/ôMD\[[m~ŠÜf'À’¢$7ÒÙ¢½ÉŸ6nX }<Р scɆúØ–¨EH5Ì ±ñóíœä’ öœöEŸ*ä¶ï¿”~4–ÒÜéÑ•‹Ç?.e:1}Ù…È’Zák®1ç°‡À螟7¾Ê‡ö»N/†|d²ÄÜRRZ"B_ЊòrÂñO&ÐþÊW«˜î?Xs\wâðvÑ”¹û1#WgHA^ëƒ(¤Ì¥Ý~›™Um싇  `(ÈPÏuëˆ!Ä<Ü‘v—_ÖõÛXÃVÎuÉùÜ¥V5*Ä^ErÛ›|¯Ü¢Hi7ž·Üu'g ¬f¡{7§¤ ‘çµ~G#$í¾XŸ'á’™…DÒ– VB’~**äOxàÀëáq"—¨y¯`QqNN‹Hw*´·ŽîÁ”`é&ÂyV £;sÂ!!QêU{g¼‡®–e“lJèå[¦¶=o—açm{ïÚEÍlä»ïÛÔ” ƒbÄ“ÅXoòR„¬^vßp„O_w®£)ê囜;¦ES—Ÿ9Àzƒ°é¶1•hó§úLªòì÷â÷ídø~®wo°ØÂ(ÞÂZg¬zÖöÅÖÑøKÞn.íï]ï\F.PwJ‚íðØB”pc={qq%~~DÙbëyÄ8àHª2 Qw=æ¼8EÖv¤…³A›ÊÇ,½RôvD¦s=|Og‚ú«“dFê$Ç­> 0›Ý$ݾT“æÚdéP[êçÃE¾fÿƒ4«`ÎpqC¬ÞËiÛL-Ò™#$S®v ðFT(‘TxˆöM4Þ­”b„ݶ/¯øh€¶´þŒ“¤‡‰ñ!2;Წóot •¸o)Wц!åiOò¾ —ÔŸ#N‡*_Ö™Á4úÝLˆ‚ ²r €±Â&xX¢Üó,u=¦ßuœ»xAår£c_ÏAg³ò<²úlÌ#IÁÇh÷ñ•bìãšc°«Ë"A¶6{JJÅMšQi"4Ø›NÚüøŠùgLa7^#,rgqžÜŽØ¿Iºjcq@1A‚‹n@c"4ìì¿öQ+P+:m 2hTBºÈµÈ†ëh}/СñLJc>†úÈW>¶†„cº^H¡M%TËÕ¡ö*Ð’žÔ?ÙP))³.„#žç¤A¾ zŒ¼x¹Z:ΠťTªŸZ5*Ý…Æ(”„¥V÷Wû~÷À;jšg’P¿ÙàòË®/ÛUè‚íòQd#+Èø²OÏçßXå —}U=Ù€'úâúdüÃßØ{´z÷§×Û !þ´žªŸúàEŠŠÉ/üP7@´Œ?Œˆ¸?É@Ž pý_©7ܾ¡$÷øúã€O©•/šRß ðSÇB AWÀ€å´¤z@¯£¯g„×*¹ËÆ—\ॣ)•Ib“#/òÚÏ!x/²Œ^ ¤go*äCL.›égß¿ÒæÇSÃ7!ÕêÕb|kÒDMðÃöþ-˜öÕM¡Ò0ö{¼s¸ç¸ÖËëëaÊèœE@RBöB£àUéSD;N=ÝêŠm˜ŒulÕJÃ"0³o"c'Ö÷øèÛs~Ë#,ê •@Ž´AÇ€ôô–Èß ôE.ðîµî7 Ô¹êÃN#,%¥#/ºñ²bcÚ@°#$£òä$9nP¥Ò€æÈòûü?læ*h œ­Î²¡Å“ʼnôýöN¼èš¾íFìË$Ú ~ðä@w½7vøªìü짧=oó€°æ#/„(kÀzY#$=Ç÷Ä,·püþ70$Í\ÅÿÍÂ6î÷Cp¾ä!¾%ü°²ã”0ô ["œÌDZˆˆ†"â«; h9Ä,ÃØÅDÆuDqo©±CŽI`#$‘ q-ª#,Ð/¢0BÌ&¦ÊXÙ8+`†)¨¤±‰$àçr‘ÍFí"0AÈ¡ Kƒ* êÛa~.‚6ÃJP#dÑ(Ï`»EÎÆEaƒ²,‰aÁ"XTÃ#˜Q‘%HBl}Z"#/‚Å_ñ!A,S€Ð‡ “ëïU?ã·_…þ±ê)fÝnäÕ ¤–å4N[bŽ®ÞØ þÈ&x}»Îg#$v*lß%bá'+e\ÖÝGðp18¤OKÂI!ä+¹؆P‘ ±4¬Hq9:þ‰@é¥[¯/k‹À¬ôÐR˜xN)Üž÷ºYŠ{;Q#$”%66µì·5²V±«|eY-lU®[W6ɵ\ªém^¬Šè¯&걈QHÕ A,U gE&ÊÊ šâdMñøWÑ+:G9¨&B½8ÐT(–¨=õ)¶” `ànºèû±^ýË7èÄx9H¥¨ÒTäñ3Äß“³¡x€ltH±h<û“yñá ·ñ®D¥},(gyKáØâZŸ\¬xÐt3Ê}^7S¤›éZM“hÖÆÌ«~¾·Ä6’áà8øòS5pÊzøè6ž#,Å“È÷ò«èÈ¥X¹ÝÉ£@Ǫ«ƒURRÊL’HËyâ©%%¯…B“$ç‘ÆK²µƒ¨Ÿe~[x”Ì#³6>WšÂŸšqÖQ© Bƒ¢#QF‚ "¬T&ÆÎë[ßV¼þuî,mk@‘!T#KåmiÎbo*µû(u㯿díêNðTE¤*«^˜ÄU…ɵO%¬–!àÌ7Á”\™•3Ä1Ç=t:íß)‹ëÉÆE%B*Í™ €°AL éÃÓ¯t4˦ºî‡òõ½–¹è9òè·âŘÖ%•xÒZP²é!Pn&a#$ Ì>~˜rÛÇDÓŸ Ú#$›iÐwÆ1$Àhöm¬¤y$#$Àå²ñ[¥LÕŠuÊðÍ}´`9T…@E¦Ȥ B"P0s¿¥*Ι4K¢R²E îLŽ<»bX=•—ÏÇeítô@C"Òók€&ôo‡*HÌêÙ› „#/3¿úߦ+ƒ©ÇÝ(û,¢eSEW‰<~(ÇÙ„ =ÆeÆFiå.ã®ÍWwJIb ¡¹Œ¼E#/€°;æ¢ù„´§ÉΔ­Û^MA† ¹ð°÷ gâ‚T6#Þ4·•ìÅì}ZÉÍÀÓ0¿N4”!í#/sm àù*h•ô©% Ö,‰tÕ&$A"Çq„æó6yGP˜¦`o£Q̵‘ª *P¾HŸžÕY¹k!Þvf;÷ykz¥}ÁÀ¢ÈÝåUøja¶ûb÷6\v†\õetoÄ “ -©¡¿‚ÓA5@ÕÏ>§Î`äÍŽveÅ#/ Á€Xõâaòݳ¼]•èå“\ºHÜçw9wÚ}UxѺÍcSK)áP¥BÓ¶ê1º#/_*¥ˆ·›¦Åˆ/õ ò><8ã'zuÞTªšSC<<#/R?ŒÞÀÐÂØO£ÝÅͲž5N¨°:9Å.Œ#,ÒŠ®ÙïîökŒªwPSKF ¡--ª%À 6Ô¬qÁ§…¹1ƒwµ×hObCÎGiAž‚ÍÊß Ù)!,mí™Ú¢å~Ù P0‚@ÂMûuÉl*˜Þ'|<äÊ„Ô¬\(Í:ÆØùÚÞzDÆGÐÇ(à¥#/¨°\Œ„‚R…#/„RH u5׌ÅiÛkÅÎÐõ£§U›žÊí|¨÷Çy|[øAÚi…! žÍu[A‹`å}ðWU Ÿ/ÓœO_¯Ø½kš†žV½xLÁÉÐϤ°ÒÈ0,16ß#$=’ cU:çÙ›ëBûó(ƒÒ¸#àÁÏ#,‚™©Tomäá‘vxûkß¿K>ëU o*&L;ÁÀŒÖ.$ô3ôÌy£¨±»ŸÓ~ÐÁwbœàu ‹¶61 9Hg CA¥Ð39J›‰’=ÔU#/µ²ÐüK»(bCÏNJ#/,YpΤá[¬Ã(î¾`pªHÈA$…á{{¿Jn“g@*o¢"3ƒºŽÜ”… ¡ƒ÷¥Ù#,“ã±âcL¸¡B™G‡ÆˆP›#/©ÇÎh@=ݯèv _†—DÅü£o—\¹c\ƒûñGFø&l.o6ÈêûlinDµÄ ®ÌCÆD ¬ïÁKùÚd±a쪇3-”“ö¡UXÐ#,Ó¯fÀ] tJëM/”BóC]™éƒ¯•è×Ãi°‡^=Bå#À8“»q$þÅ·Zîez"ºî<&ºi`4DvåÐ5ÊŒŽ³.5ÕÖSÒ!1ÈÖC@wÄö2•8Äya b뉶sx£Ku–²yZV©k[UÇ(Ž²!œ„³RJ/zuâæYЋ-ñ»®ÕËHÊ&‹IâݶM&L¦Æóµ½Æ-zm}Õó:÷ËlT¨U)Œœ±big}Íϡе!ÏfèÉ NR† h NíÞÜ9cX—³•ðµ‹l{¯SFCá\ìQÞ=[‘é Ò•vIšp¡çe§}Nõp {žê¯ÄuΤ]"QzªwJ"¡¨½@å#/w›‚ú®éé­úŒ#,?×ÕØdH¹ õFýÅ ²Û7ØYÈ2bJ¹ÆpZRþ¯–ºlŒ à–?0îß«áŸ"“B“úŸ–óÕÎÂÌ¡âÃØ€«!£È*"Gdµ`ýt|Q“P€>¡¸ ñú¹g«î˜í£ÊÏôàí“îJРþVCãŠ&ƒK[¥n>YÅ•^òYßü_–a‘é±>{µ}Õ<@@c×eð†QK#/-n> ׆‚œª²&‘0ü)ÀxÎúÏ÷€#4º#ß6aèâŸ}%C™†?ÒüýÓ pÌ}†îÑ=G/‰…å2’ ›¿í~8–1q4­–=8×Zbo#錖ªL6wÍ^‰©& Àû>ßÊ»?«öá-zü0¢±•„ÂÖǬAWõÿ18&R#/ŒR"å…¦t¯ñÿŸÙwÃü7Ù✼wùâÚ²ÛÃùNÆtÿ<)#,úÔ0’t~o èuÒ^çÇ›ŸÍãñÕùoC!óŽKýGô÷Êì᳦——Uá‡8XAWüŸú¾_õåýÑýò'øM‚ÿÃýL`÷R’²Z‹X¬ÔZÉœøEE;ò¬é °¢Ü®£:.g©=C§—vC~pˆ„?÷@)ûr->¬ûš†––Í-#$Lb.ÙÂú65x¬Ë …ñôܙɉƒ»˜˜Ú)Z‡¼M2é_¾‹Þü>ï˜,檡)¡>ÂÓú>{øÏv@ŽPO™ø˜í…ðÃû¶MÉ#ELÃHLÜüߟÇÓÇÏŸo£~Ž¦hÖ™Š¬5¦yŸÒ“¢nmoà›t²Xµ2½yÛùï$ót*B’v}- 9Å>aõ=ß/®n²X#/IT~˜9ÅÞÿà#,µ<¾ã0]5'œ0×zŠÓþ™ôÈrë¤2ñÑkp>ÏLa{ª';ï¸3Å-« ”)—Hü;F¡=ššib JŽn=xg®²Òâ?OGOû]Ò¿îˆ6®)!uDòߢ÷Önìaj ¶0¶ˆ>dD \ Šæç#,{%KhÕC[i $ˆã-Ì2•¾töùòÖ@ÙàèxýRå¼^zµŒqšàŒÖýDŒÆY˜1ž›WÞ{Û “wøÁ>OžwF#,=Q”!ðs=ÖúfÅïAÃH:UF„ŽÆŽÿ/^¿e©î¡ž’ªBÒ÷ù}Aqáô)·õ.šWÐÝQ²‘š®ÆºÐŸ]@Ëý>lG>|¹4™`á?™¢°]£Îrô.Ù銻J†F¤Šý/*èžôDÈ‹‰°Ï\ùÿtýÑó‰²À×Û ïR122ûÍÛx{1ùÛU]%®½Eh‰I8 NZØV@O𓃭õlë}C»wÙã·ãþC>>mzs<—ïŸw×ØhD•Tô\vvèìâî~ƒËtý>Fxu|Á¬V’¹VLöÎ0g:öñi">gØÑB™ml}<‰Æ-ö_Ð^ï|yº9yÅ#,Æ¢¡œ÷>:òYžë‚•ü™™Å¶¹›c Rž¤#$íëæ#$tëéð²@¥^¤D+wX_-~oÓó"aÜO“Ê‚Ä„…V7’ÿfþçú|¹…ÐÃó±æ¶¿»Õé%ý]aÌW¸³8+ùÆ~Só<œO‡9MŽ\nšþzöÊ#§X°ç—oÔCŸ3ä…ºé윋ç¢1¨al¾Ÿ}ÁÚ?%úÊ9ÇðíäôwðÚ!ò9¢½{øSÏ[càOò‘ë\_ä—#,¥ßÀ¶¹•Ã+`CšoíûþÿÓôè¯Õ¯Ž¿žk·×éÝW˜#=§ !¦eZ)#†uP}YyhòϼMnŠý—KdœîÃY ™Ú½¿„öÑû½çºÉèpë×â<þ>d©š*?}ÿ¾­#,Nd*ˆˆÖTH9àèÙrÀëÊC‘ƒQ÷êP^дÄ£ýRøú¶îÕ!òŒ,OG:«n»÷7WUŒ7ª\Ü( ð‚.#$2&_®œ\|¡´š~Ž9–±1Z#/½•BÀA¾ïïE7)À´Æ°eqYhl*B·IÐÃpÄ„ñù~Žg_ê+ÀoåÍÕ§“æ“#$0 KZŠi]}=ª½fbS0Ò˜¤KUƒÈ»Ž}(•…UH°VEBž'™„Ñ{™œ@˜¶ß£§;8á!œ¡£ù³dÿø¡Š”­ïð§¯Á>têj½¤ˆîöÉž«ŸÂ÷ÆÙ4û§½’Ûðžt2ÆK¸îæÕšu–UJ)ǽ¦ÓNx¿.ßÌϬàt„€pq3 Ì™‡4´;oƒŽ#­•VºV#¬?Óövfh¶ˆ=‰ÂÎ߯ùy°¹æªcÖ}»`aŒa`¸â#‡hµöùûz'¼’§âýçÙøžŒ²2.þ}Z=yûǯwè_½T?P^0ûgŽ#$iÄ#,#e‡bÔ۞ƃïB¤3œ¡{æa¾û>Œ韲½Ôœ %2¦¤çá‚?Ë·ò¶Æ†ñÌš5åÃG8uü k/3›¬EeÙ˜>­i GÊ`ȈtÂÇ5cUh»é›ÄéŸ^ݲ»Ê#$0 1#$õÔùà7mw+aúôù=ÔöòÛ0ˆ2 eÉQ[@ÿ¬36]ã ò³n—:,üĆdp­¸_®”dMZ€P‰(ïêÃ0Æ#$€ø€ïbŠýÛ[ùjùCGS#½`ôùÉAô”‰ñ}H½\óóP GÊú¸JH¡ o|lüì3œ§‚ÒŠáë¼z†æ³Õ/l:C]v±xîþÿ̱šáxn¢%ÎéÍ8ñ Šó¾sz$ÓáªÝC<æGHŒKŸ£êsq!Ym*Q¾’h±XÒ¬1‹ààº\Ø8(8(É™"‡Åì#,E(ÏÜÐr²±m«Z¯5`Ñ[ˆs;ž<³UUâŸUÁ?ÛXÍÿd™âi)•ç¨4bºÛ×±ñƒo¶ˆIl…éÃí.ŠIhéz¼âê“õ÷½:+Êöö¬åú¾7˜3*ûKCHîÌÂòE¦µcÉ}kßþô‡©œÆÎv‡[>äo•òU7siˆ®ïï·ÝT"ðôÉÞìtK~÷Š÷p²}0â'RÚ¬Äè*ÊÂxKuèXêI¥–NÌø>MÂKÌt:SM’ˆUFA¬ˆW•é*˜”oØ£˜ÑåBâ·Ä>бå C¡0¨Ì 7w˜è™ù\3è¦çåヰ¹±µy¶+ŠÂ0MÇŠ¯®| #, ½<‘þ;*¶<ðVüwŒ×ø ¨9ƒÄÔ7ƒ‘ºù»Ãh ½Gàh)\‹`Ö<øˆ-ã¡lÕ]EïÇ®ÎZÖð™[¥•ðRӇºyLâFõ3úõqµ‘ÓÝëßhsq8½t!×OHalì«Ü´iXE¦ë%qaÅnúÕ #,•a|î6ÛºBI¡ö ±¯Túܳþé¸çK‹:ÉrÛ⬠#$Nb Ü­6Òä3¢•ß­Ù#/¼{o>ZqAœÎ]Ýl~âS#/ºSzvÞu<žêàϬé´VrsëYêäÄîø‡¯¾³Q~Šq.-ý"ŽÝ5Çzλ\êž Ç”ª3N=Ž}ß ƒËÏ2”ñqêvt03†M9úd‚#$HìÈ·(xbq!(‹±û%²ùÕUw{¾»Øõ¯â_¯½¦ñSåáaìÏ–‡š¹Ï²`Zo!ûV#$a…;ª›}çu#/ëV€¾íOa©TÀ±ÉX¤'³?Q£Lù‹ò¢’G}²‚<0!áµ=ÿÞ¨¦ÕE©I:)é—Úæ¡Æ­ˆSí9Q>Ñ÷³ á¿´¹³°˜§ÛӯÝ4p¦úZ†™E9¨‘BKï<ˆµÚG–æµIßÓFùܽ¯®£IlÎg¯½;O[Kâˆq×ëƒí‰ö×6UN_D³ôú9÷Èé/å…TÓ³lþ{îlïÕÄ¢.fÆMIúß?S2øôæ"žâÊØ£²1‹¯íßmaÅÏVümŸ)Ñlu§Xp¡:GI'wÒ]çBF2ÿqM´|"§Þ]Óº-ÎðèJç³OƒYÆ%bc(¿óiüø´ž®ª¹ª¶DÙ¼RѨús®æ…:s ð’‹ò—žbq—Á™•]\ˆäÃíú¦:Óh(r£'òë3çyÎzÛ唵À¶¹ët‰Œ|‘h~œ´EMIÚ±q8ܶ\ºá{ÖS-vº|Ç&J ë›Û@ ……Ý\ºZ÷Ø&¨ê=QˆöxÞ«¦M#H™q&ùþרÝ6KOáïUj÷+Á1(•"ëº67Pʆd.âáUp$ r¢§-2_€»"§ö¢”ù~72KŽÚ'o—_v<Ÿu—“rNrúýr›?ªÎy/YÐ4µ§NØq+}óV³ F=Eò|"#,ßßUGÒ¬ÛŸE§ídœ»ÝÁñÕÎ0ÞöŒEfCe™g©uÏf£û¶¦ïÛm}”Ü}ûpDÁÄeÕí×7Útq~@÷²96¿×n?Öî&*Ú%B¿h?X ³Ìvxd~-pUFEˆsÐ8ú.°)ÃSçéñõ½={Îp¸¤Hdì?Et3éøÄ]úøÀS|Üø$|ó®þ¯ß©+g}cioYæ;­ ª9+óûðǯ}ðûlრ@®Z–ŒÒpÂÀ@™ÓÈîñïØêÀ@‹Âɺ}dEÂ~Ÿ(¾†‹¯ð^_Ìg#,iûäë?='³p{§`ÞÌAéƒmMG,¿òÑAp KcYŸ{ñôy`P¸†ÚsRŽ+…sô8t%—üStö¥Ë;¦›~ŸeÝðO‡»M÷¨&øxvV¾tbMR’˜v­ểÁRÚMܯ­”¼éàT}q§_!3´óôüÊéÙÃHvOÔˆŽ5hd²î!^ ÖzÌrá¶;8¬m#܆ cqÙtÅÂ)3‡‡c#,aU#/%Ì;Kx¢sø²?Â`ÙoL0k«ËÆùü=×#,°ã,øæŒcŽcñ¿áº~r/wÒaá‘ÖiÞgŸ³µõÁûTNŠ‰¾ Ã’ÞsšM¨J磔èoÉÜåÙð™?‹R³Äa~¬é×oç9/„b ßIÚö¹öAÙ®bZiwy1¯É¤¿[=û’hÁïfÿU¿wÝ“»N¶{ÐÔôÖ÷ÅTXPD]Î*çDíCEÇù²4ÇIçIÇÜžvO¸Žûz×Ñëç’cpÌÚUÊUÒ@‘ ,#$•¡ub9’_ÔŽL3Îq‘~‡X›åí‡ã³ñ¾–}Ã!Ù½JNiõ0ôeä(ä‡b<êÊf—"'µ˜g›)£!i=¨^(¤À,„”$ b¤K¢ö—R.&îkw éC)Ey(ëT±dXXy§~Ìv.å#ïõzšÁTS ]"Ñ@9h\m‘#$`OÑtEX)+#/CÕ!/c¨¹!„¼nGóÄ¢«¥Vtª/®#$IÊ/-VÝÚK ÛísN±#/{<ò«ìæðÊÁÅòÌT¤.¸X³ @°ƒ;®#/Å|’ès…q¥^sWPnf[ŒH™èKA¼#ÄI æYÈoÃc¤žÊÊkÓLDX-zàÔ#Ôn¯é‡äoM '£ÐŸìçM]Ã×kò6ßbòãú —="Gîpî–]Cgb¹öþ¿áÛÑ v’ÊGGH`¸éÒ<ÑFüN§ÕÏœ™Ê%?¹vÊk‡°§(âïú“ÝúSùý¥b6Ð`Eáªö<=x[^í‰cÛºœkØyŸÉ‘ÔI$ÿl«Ll­¢¿ÙûÇ$ûzýÑå³G3’#/0Ôà¸@Cô¨è#$ÌÒsýÒ<@¼jœEõ8,‡Ð\K#/SÁ…÷¿îù^¬ï¥{#$ÕöîŸâÏ«³oaõò®¨þ¨He™ã­ýCÊTbE´\RÔØšÒX^µ>#  “(0@$Aï²øΞœ †¢ uÚ¶©•ÈÀ›¤ÖLøãU̼:G릂=âO—á‚·crvx‡åPw²#,J€í^!Ê€»z†r‚‘œvKG—›ˆRƒ ™ŒÇh¶¹BD”è"Bjƒ+;uá¹zCù¿äþîro¯žçO¢8€°€,=¬¹lJ‚‡^¿,. #,JCÏ»&Í<þ}aÂÐðijü£2€?#$½J Ç°°e^'Zá|…ö­~z“ç>ÎÞ6ó;ídÙu!‰5Áăº^ái¡¦uŠ.7·ÉãDfk–¸|z3çs³™D5K±'óS#$öÂq7´ñ&¿-#/SmLzP>:Q8öw76þ NWU¯†ï(¬¿á§sºZO* ¬À,Á]T¥„qX.žSQ%x]}ïv|Él¥סTÖ5"¦¨²­¤®pH–IÃ97ü7"7F~Ÿ£‹(4µg7½ªøn‰¦m–W^JNãgɘe;g•ÂTüLìq>ݯ#¨,㇄Ž0?J £ò‡¸›¡NExÚ1wð2˜½Û5ßU«j .%`ÀwÒD<ò¤QÌE´Ñ;Fb“ÃŒÂIB8â n¨X”¨Þµ@rÖú]Ñä6#$ý3TÚJ#…þ|ÞU#,>”ÕÏIbóYÀuîc¸;r²E¼½üóåÇPmSÀˆ_¶v?L_"'(PwVR«6ó$¾ZgŽˆöWG^‡AEÏÒ¿}J©Ÿƒ#LüzÔ¯—›ýÜèô´Ò¨õ¢g¥CÅ™pùŽw®wвjš%9E Ñ­Rnæõ‚Ì#,;æ7ï Þ±¡ÖºkX~OÇü9Æ8XR[ú›¯éüTyd³­' êóü£Õ§qøÖ¾ë«õµÏîþˬdF‘&{qÓ>zè^Y«äßäxÆË9m°~m[ΧìÔÕÉݦÖÅ•øuYÆÖ"šã9gHXÊüò_LáûÔŸgäšÃáZö$¬&êÓ'윇îÇ•·#ž\ÉÕµÖ+£ùÓ·i‚ÈJÛtRïYÆ€epy”î#U$ˆF:`óFUŒº\£ú»x˜á7=Z:pÆ'I®†\f™Ah3šE• °0õ\ënµœìK¼‘Ç’ÎÝêíq tKD,€Í…Ï•î>r‘Ìê önùg ŠÛ¯šßºMÖ¡xM­ŒoLÕLÉ·ÖãÙl²[ž<«½¥ºá8¦¸ÎñGe£q·2@¶A4ÃIX¬ÌÄ÷b7˜4‚\#/ÇRuãÃ3u·gÏ\Åù¥·C~¨Ž_º¢ë_íã0Ï€º(/×tséu6E«¨#,KÚÎÔörÖV˜ƒ³LZ#,Õ)ç®ùº°E­óg*îmç=ñ«­g¸ï·ª^ Íâiöó[­a\Óˆ4×Y\ŽÇZ#$À¡(ÙN#,E8®oPÍÔÿ’ÙJb•‚®3Ó;¥:ZÌêT‘Ut%€&%P€bÆý~„dôôê¤âó„«¢oŸÆ:Y}½ë‰ïÄ’LÕÀAï#,|°e…;$›ŸÖÈQŠã‹úÞTD.IŽNØ$<³pøðñÞ! ^E¹gMõZ­›§M¼3ƒ;o· n=z¼î™¾rø¥‰õ¹:õLòómð.¸ðç[îÑȇ!2\DCí¨#/"QI³ûï»n±…€áC€‡€lgû¨Ùmëñ ÷‘øÑmÃÌúAâ`­Œkf6M¯³±ìÀwåïiT|–û‹&Ôª ²šö”#/ÚZõT4±qeŸfFôgÃüÿEËñ–å¯Cæ“ó|ío˜§2>¡¨8|}gGöü¦ßF.#`M¥Ã’¦yŽðétÛ™ïÕÊ‹zP­í0wN„C½¹¾XÔÏwÔú±ÁÝÆᓨuôpd5a¨‡è_²#,´ü»³”#´#,$‘Ì”™¤Y÷䦞ï\ëí,*YÓÄ6©]#,²^ã¦Xáž®ì0iá¶ÁɱWI 7JÖG¤àüÚ¯ŸßôŠK[Àäëq@ Ø îxÜ.Ìi´4Û{WÙ[dzuN"Ū,vÚ+ó|þ­XÝJb Z‹j\æÌ{‹‹ôÀ+”½Îi(sÕ#–n½4ìØ=Ÿ­V*ª1§ Na¥™‚ëÂLQ:€QÚ×ÜA%9¶HòäÂ3Û0vy 5Ój^ð›$2}Ãu)-ÀGŽ¶òye”„0àÈ 4-šb»×ÈÓøí`Nà+Ûbv‘“^;QÕØÉÙ/,µˆ±vî¿n[ï‹ðiº£Á×ÿs‡$PTÌ.}½í*©AÈ·#^ËRêœ%‹¢ð¨¤ Å%kÃ’…Õ„t½ö—¼›U±G?$ ŽyâëòÀ`lA¾ÁÙdí:#/_ Ó¾û´&¸;¶§´ñ,‘ƒ«hò–?½FÈî1˜]avÉÏ)æ.Ì€f,”¡Ï—‘é–‡jµc¶ð5¯Öý¦üLïÏNæ’Äaž"Nk32‰Y,)š‰Pc!ƒóÀg(Ù*$T Èœ•ÔÁ§“z]<ÆíGv¨'È9þ:ÕrÊz¶ƒ«kT¸ˆ#,,3!s(PiPÚë37oPᙌ6öŠnä[]fx» Ĥ׾A¯òá#ÎŒ'¤é=©¼ô=©$“õÀÊþy 䂶@\,äD€3¢8†O&Œš¢,ÃV[ãPYƒ¬‚()qSsã«É;ý´õ-‹]Ž]·ä’ŽS±"õ/‹™¬0¿˜B'ÑsÁ¾Wë$Š“³m#/*ºû¢üÔhŠ³F@šÍóA#€¹ì{Eame (49Pn)Ë›¡÷•êŠž9Ôï;ú=¤Õ7/Ô¨¡uÌ4œé{—Æ cQà–›þ3ÜŠo6ˆÄ)!Í6{…F̯˜Ðÿ(ÊÌ—«@ÚCçЪXDp½†]¸jÚ;]§¨[n@-*à#,‘×YŽÈß»î#,[ab¸@©X÷VØo´ÚA!¼{JÞÖ3È8¢(kHƒ*ýîùÐOwhð²§Ce/ `3¹Ÿ5]«n0³Ø0•¶9.´X‚‚½“éëﲈú-ضsŸ¤ Š¶è‘hCE¨j"àõNª7èÀu4Báé™8:+8¹8 ŽŒŒ“mëÃCFتs7 ’ž˜0x`kE J—‹Èd#/›'xµàÕ¹ˆ•²êw/Îص†Û–Þ° „†£"::Ÿb6ů}’ˆ°Ö(§·º^Ö(ä¹Øf¬DQo-×ç]Ö^EH/«A_¿8ÍnXf¸¶›Ô‹oBR#,Æ[áÙ0÷„bU“8®H’!̶¿f;l4(ÉÙÛ¼WvžðΔ"oí?oçn©zh\.Äe|ÊJ×·5Dé(z#, Ç=µÃHéÑÃ,mÌ\Ém X@)¿Cl@-Üè%<¢q¤^ciÎÑ8p»}à©Ì}¤ÖG0)%µ¾=¼A2þ%‹qnž_„:[õ¤û•cñ³#$s=âu¤Do3r"rÈ ò–¥;Íbù¶ëðzàUö‡Kl4 ²A.з#$¢ÛhÆÁæÜ³Ý /<…c\q±)i8VÜkjeÅñvØ ˜ØžZº®¢k_·\ÂýHÂ5ׯ[ߨ`0"áDtiˆLu”ÄJŒ‚Á£µéhnÀ>o:/¬¿·Êœá#/El\¸`!‘$ð঳Ã\¸l#$¼"ˆpáÊüf£ب·#$<*&ùÜÐA@n~~~·á<8œ,¼[ l#/ È·²"{çvÊŠÎSǯªá«Þ¼.Z¨JjY ³_$#/·Ôºšé2ߟW5.ù­»Ióœz)xwò–#$”Ùý^­Ÿ¯áî@ù?6y9ÛërýÓúD4Qù´( þÅ–‡ÞvtŸ;#/%lU4â<¨$…b|®€…P°DtªÝ”(Ó8ñ'ŽE©¢j_åaíùº‚:ï?T´Zñkì;Ç ?—Ñ[SÌç8š†îf#$>øÏ·rók 04;Vv8ŸQ”ë»6~Þ½^K»:³ãù–—€ó‡žXŒ²‡òíãúÃð…¡¼«k¥ž ô"~Ñ¡Úp뢓µ ŽÜ1îgc§?×UU‹}¸ÿQ¾|½·ûîÍt#/§YT¢‰Jœ0ÀÇoõ³Ý_‡ú€øÛôpÛùÃö|?\Ì“úÐÿPþ• P`f¾FFpÛ™þ­¡¤ÿj’2Oïa.¥P;ŸR¾ˆô°‘Ö.ðŽ°lh° ð섃 #,§öÚ&H™'ųþV~òÞ9j{{,o>¨]¹Û™a·÷ÍÝ×MKpÿ]@£ò œ€îG!À1åÖŒ/·§q¸TÑA5Äó†#$`N‡‰¹‰^¼Í©=¾(Ž#,7zô ªíHaÓš7¾¢¨…uEú£¡¬×@¶`K]U!þÎ!•ÕS¬ |æ£Ö=¨ìN°`ny{C«œaï÷±ô¹?Rû>ÓEAÐÕ Ob;"µþèªXÀ;`]Áñ'X™¥–‘Í…î\ý×ÎÉ5#$Û?[masö>¼PQCPÕ!ê9þZÛ™' }«Èu ÿ6(‚nüßʺŽþÎÛ]MÉÎÉß„ nöuOõU¢UÙüqÓž Åš¤-ßë¬ûAs«_Sõ=±óÒ–Ë#â¶ðïOPÇ)WåÔÁónˆ8½€6ß:ÂVW‘Ò®wúðõý_¿…·rõ°kmd#,š€öT$híý¾Ž³ÇÜëÇ öaç~«V{sãùç.! ÊLRª³RÅßráõA›™£tKåŒ_"tÏö¹öûO¸4Ãø™ƒ2 ý¡¤x‚+øwOØ\œõÍÚÚ¨´f!f KŒã†Ýø$×HÝæ,#$?ÃP3r°k#/'ÞŠq!ÇÃb`Ó˜ZŠÅb›Hblµìž@á»*CÙؾæÏA‹ûÔ0é5ZìÚ ¹'¯ãÖ@~n€ðZuœÀ໎}»A6-—ÜI™¬ukFÕúPÛÞilý}Ç ÚyX[" ÝK dc',¡ ÂÖa¼qô¹í. ±Þ´¥Y zýe²d E9‡;˜‰Åy²$s©V5ÅظpM¦ŽIÔa‡W•¦8„½CÅ>Q~ô‚µ#$ç>Êñ½]3¤Ÿoع;¿ÏãÞ²GÒT%X{<‹Báß5&ìó ¨TQÊ(ܳ`cÉ_Ú^úÑòî„ÿ8ú8æÁÀH“_²6£áý,¯ówßGц@’V¨¬ ~œø;¼ëû¢Sou.m‘ ‡i#/⥦Y…Ly!Ô’7÷¿ÓŒÉºelúÙm3¿U¶Í³>Ú~wÀd¢³’âM†#, ™’Hc÷¯Õòöc‰ßIJÃÛïôйUï·Â¿#/j+ô©ý•²ª0Ð|£çHB`,)$"ªöGª¼ O„$À<ÇÀMá±Aª9Xòü»pºi#$ùL¦×oá‘ú$ÿ7²7>¾­è§è8‚ŒGË3S¡”hÃÃÚKFòZA’{Æ“Ûàmàèpˆgø~Òª¶ðûÞ#$R–þáNâ ’©„J€—^7=fÆ÷:‚Jg0:àÿÔ™à͵.Y8ñ¯èyàELajÉv¾zL^àÖšÔûž¿Ž‚ÖœtˆgxÆ-Ù$°RUURª¨é­VÃøùò“HNþ9Ï^¡ô:…Kõº·\?ÐzÌw<©žÐÔó×B2 mÈ:`,´nw<fÊ–çñΙSnÄ4[V –wÇÑOÞe³Ì>’Ÿ™€…~'öÂNf¹x#$‘ûÿ·å¼íŸ3©à%,Iü†é#„—Sç8%ýù Z`¤f½¢#/1zøŸ‰ÆÉõÝUê6—ï(T»’<´¼bB‡ °3# ÿÇãåû8lqñ£íCµûOK‹MNºC(KDfÞ.— •k§Lµ[”1èì@.Œrþv‰E~yÏ«ÔÚ±£J"ƒHÁ¢Œ^3‹«ÎsC˜Ç>‘Qik*,@¢#$há­ Íúwëص&&ç'qGÃÈ1LȆb:‰¨!ñ Ëìû?å䆿“óéÚA ÑCLŠóêSaµ?7 z†G:»Ct²å%¨¾´#/À¡Aï¸u†(¨#,Íh#$…ë…ÏSÆE8ΗßeAû•05¾,>Ìâ¯"öɶK‡#",Ý#/jP#™SpŠHã¡M)ƒ@LŒi°p`vñ$íî+à1šâ@ø·T‡“Q#/D×[ŸÛÁWØÍÎ ×Êv „rž“ÂÕ›C¼æJMtàk<òJ1.¦ Ba¨’Dp(.D?3ü}?Qöuì¹nÛÑù Ä.Ñùò`Uq’’kºWú=xkÐÛû.k§¯]RoFJM3"‰1Œlå×,’ÃWüÿšæ#s»%¥Þ£p‹LÑ+¬¬Ñ¬ÓÖ™Ô!Ò>¬ÓÓ’Stnäl³+”¤CEœHëÉ$’LÕFšÅ&*eÖ¦¤´µ¶ÓÌÕÍYk5˜ôÊÌ #¯u uë:ߘœ)ß¼: o-°‡.ûB^„CŸeK&²怌QHKõy§-q-ÿaóó]¶d>a؈ZjH M)ßQl‰ÐªïVY¬$ˆ €r¶QI´|àÉ’tÿ»n5ŒäвV÷ $“lCÆàÖRSYÛ¢e{æeâQ>˜–—%M+ô¤Õžù|yj6²ü#/|øÄã¬óŠH§ñß³GH½æE`}ràcè{±S`ž€Éþ0µ‹67$r7Ý8í¥0;6¦æ)$‰"ÆFÓôߎºq›µ)¹DQB™H1U@—øöw]Ÿ}ýåø'iŸÒûÏ°>–:¾ïÀÇ#,]qÑÙØÒJìúÊÒŠŸÌ,,ýlbÚ .±}âBéõÛ‘ÿ‘©¿Lô:˜"yEó—ï=ݯ5OoÌ‘B%#!«51CfÀ<挷DÕq d#/b«{³RYP¼P %(³*&'åñú¹ókˆni]º#,½&íëì‰ÀÁ~Gß8ÆOAÄ!h(¡£q„=Òb”-?­¶)@(˜ 4œPn#$Ç—¯¨^«xN6#$ÓhvŸ]À/Šè†!€Ìˆ¸YúµïÁSʇ#@#$„òêìôɵÇù;ÎJä[ÍvñýÙmÀ‚ŽÑð« Å'º¾»TŸ^‹^ –ô½B)gÑ@‹Dû#,ˆžV8˜¡°XC—¿4׃"„! þs˜Cëh;ÿS‘ÃcànÍ-Ðç±8Ý×úŸ¬ë>†º§(ºØÀÿ$ý#${zûÓð7rð÷#/vR‚$jèîcáØ “ŠQ¨~àñ°E ˆ{¹ô®ßqä­ gÃämÛÈÜ5gP;½_gaRÖŸïåØnP‡ {{¢BÁdŠB,ƒCí<‚kê :•þS˜\¹A=¦%#$šüt¹Üœ»3k»€¨#ä8!É :Pdñ‡_{Tý`T>¾®eÿ6>ÂÈWÄš¸/®+ò'È}OªJu«í/UP@,#/Т„ÚºM˜Óç!w{‚ã{ì@ć)#,dãO†Xª¯ÎqTòSæ ·õè!V+\ÆÀÐ’#$ùøþ•~ôŠIõõ‚qÖ¡§o2ž×ÊQÕæÑ95~ÜÍ*4ãF¸µ™³+d=Ècs:5çR'~bwª WËÕ¹a‰‚¸×ÌùÒÖI˜nßxmÓçé¨`DÆ]ŸYUûØúž d“ê¤h`ï]ÁÒÂÓy@§< '#$±aæZ‡.C³¼áùŽ.F%%  6à^¡x<´¤>ã%Y½U¨ˆÒ£å%MÄ5OåC*g2Gׯ'– hJeþšTN;;Ô(q Iíöýòˆ‡š¨ŒdEQ*BÎ:½yóvÚhÌpµÖ-ÈÛ7’-Ì%Îç¡\ÃkêßêM|ø¹L‚*ïâ<4™aƒ"H,ŠÈG@¡$´ZÌ«Fþ¾„:¦æÖ!bR%?.'2ñ>q®b•JÁ®gN€‡Ùßòg©ÄIâfVOPu«Ù»|æˆ+âƒÚl5vFÿ‚[7ˆdNò›UJ/sÃÝõ<ä}µûôû<œjöå%fg„f)_­oèì±#$üœh‰¡É?Å*(ò©(Wþ§PÕjðÒ ài‚¬é´|1rFã6¥J!*”•ZFá«ëéÕÛ<ÎÙ;'­÷Ÿ#/:ÔÀr‰ÁÂ"ýy4¾ƒíB'¢¢[ú>‰%膶ÃS#,beìv®ãG¸ˆköÊ=€Pâ±õÁârâqü?#—ÛЮdðSÐEŒªQX% ”Å©ñSÁ8Ÿ`ý¸¢äCuÀì;)N¿81AÈ£³‘:î›™ëä€ÚäÀKJýœïOMŒ%ë‰]©zâ%‘O–£w¿«à|Ǹ¹`±bÁ0¡P´pú¿´ÁŒû%hÑm#/œ£ßåÏ—íš bèíÝŸC Ð íg…˜as>ö‘êšÞ¥Ü¹^Ô[Ö‚1.?B1*g2µ#$ÒI,Mð¼0à8÷2$° 4ªÆ@R„Ù‘Mc& Š)ˆŒ1rAH1$Œ‚#„J*"9.Š ‘àÁŠ#/€H9¦ !£R×àuàë§ÛÜgîBŒÈØÄîïÂèždV2I ’À;É$+#,€ ëe$Št¾Ä5ëO@~)Û´ÑLAGÓ¨±,”È3­ `Ä#ùü·‡-‚×7Úœ-kÕq†#,¡èöÄ#8­¿T$¡5ƒ÷ÜpÁñÚM½£E‰LÊ#7˼Úù(×5^•ÍÒ6µÓ#,• ˆ+-–ÝמeÚÓË®x׆±Š»ýÔà_/?žRÿ#$7¦áãYõùOõ¾{OX%åðºçíf ýd€K^“ÜE,äú¼žHÃS­#ˆfi‡Y±ú´›!úA¤S³W’×·vÅ3XÖM]UÕ|%­$hÃÊ6lZž¦wäD9‡¡"‹Y à¥äò”]wñuî8IG–'3}ç^Tòxà…¿–—ˆì@Ó6îêÚŸ”ùÑI8Vø,ÝØ8s¡åY½!¸£¨È ëØQ³²![G‹IË:ܳ'ªv[¾vÖä6â‹°Ä7L-œ*c+éeg¯ï³×Ù•’uÀŸYY”˜’ç¼’'ì7KK„¦((¢~õ’§ù€þOSèÀ_x´­y{ýÜ;ýϪéõGùTHV¹¯Ì7¾~ÿ÷=u*‰ ð„Œþ”MŸ!hU¥¦f7¦L0Ô…áaBÔ7¸£ÜY%Y$‘÷¹êÁöï“t38yvkR 4µ€jbA Ì©hxÆÙ9I$!»‰ñáE!ô&ÀU±HèQ±ÅÅ åÕüËÎ2 ò@5ëR€Ê„7¦˜ X>¨ÏW·ôB¤´ŒÚ{5#Ä:Îä1B#I‡W.®q)c÷QGhIGZOÂHCò†/Wj¯Ÿù!#Â\iO#$²…t~àŒ+@ädæñŠÈÆ(),îg± –Ð%ULJšX¦E¤459y|'Ø—Ø#,UÇðAò¿Ý…#$oP–C"?”ŸôgG‡ø„©ý¿3ãú àë,¦¹1eA•VŠ£ÌsÎ þL)ʺüöTâ!_Äž©Ú žy+Š+.‘È}l)2_Rp°Æq'P‘&1\ÆÊAŠAüUüR"àü}.ô õ>!]ݯL튔zÕi¥‚È!qp0>ðv…›æFØEqæsÉAc²áª}PºqÛÚkÜ"#$¹nW°>Çb*A#$uý+%ÅŠ©‚‚ešºŽ³Ž*t _VÏ-CÖ§PuXoz@ÙƧI%àh?MpTÔ#,N#$åeIáƒËˆªtà`x‡’ê"’HœÌ,X4ö¦ÞÿÉ£»Î¦ïŸ¿ïóÇ\ú|*Š&Î'³ eU B&ž¬K‹7æàÐ .h¸Mó‚vbÁý*VH¼Äx™ŸyŠø–J‡}·¨O_Ë¿×Þ[àûç8l#$Äx‡zî×m|m2GMa˜9*ÐýdTÔgzr77F$#™y¯D°Äa#$¥ q7^¹ÛôBzÃÉä¡ÛÝijÌ;1#,åÜLIªÈª¢ZE³owup8pœžÍgY¢0‹° ”#¸þH~'׳•A³¤ò}î´(Êye]ûÕ1‡óï;Æ/¨}`P>iwÐJN§¶za+8$„…›gq <.ÝÐÚe²(çO³¯ÏËèì-9}ŸçU([¦ ø˜ã¯ÛýÆbÖxì¤ðÃp[gžý-RÓî&7 ëo™œÿhÒýJp$óõ#$©èTˆû>pºÓ­¡´38…ýÌ\hÏÓ™òÇ™ùôÎj·‰3ƒÏýËýX6vu•Æöq¬g#$9Èpû y„WâêÖÎèVHG#$*ŽTù!DµÄ‹h¥Ê‘ ’"7diz–fì,P4QFvqиè#,·S‡­°CrPm‘T•ðÌ´7Œë2lA.€ÎàñŠ¥æ·¸À«Ü]œÙ€|ÿ2Xþh,†[âH±‚Èíè¨÷PT^ÐؼS›Çµ1î¡È P˜‰h+Ú$l¼Ž£ƒ·ž™4¿OèÛ±À}Z#,“Òº¨ä8Öž2‰Â-ŽEz.K8ZªbÕ™‰?zÊñØVÚ‡m5±lªlÁ#/s‰0lÛ=Ép>àê@ÃYH^Ì` ’HB2øü~¯±°jçôÞ3îÃ"€x@DbÒÚ!Šn°­Eþóëz7ˆfèm–ÝÂ1ìqõÙºÈÀ®Þn]oAœ¨Í¸HtäÓ§àÞ7l»E½6ÿ =^A±¼O›¨š4G$ò…­#,k.תR@Ì`u„’Ͷl؈Å#$PX°LÑE{ýZçÝíÈÝÝeéžyy!!#Dú"·vaCÏ×áèD<¥tµ‡Îô>Yû(}¡s!òAˆbÕ_ŠY áìNÙé>Ïy¼@°÷ÆRûzýwGyÞpLA¶Ïy.d?ÂŽïg‘Eå¨)]þ¸êN<™Áù<bH¥íü÷â¬ë¸õ“Ú‡Êõ«xI–M—"þÉüvb¬c„óÿHXµ¦é“ò¶‰V„žß;;K €©©0Š?ÁR™íÛt¨Åyço0]wK×v“2¢éCt ¨’ s$ý/ô“üØXÜv€råßP”ÐvSÏòÁ¢DGâ‰ß‘"þiµû¡Â†ª>TsÉ«p¦¼è @79NP›’ѨYÀà—ypq>%B#$¨ƒó|À¦¿ %#,{b@¦üÅá¦:û JôÕe\>„v &OòsÔ¹2~¨HÃó=¨·;Ì{wû´8KÎÙ¡Àõ”ÖJ!žEC*#$=ç±Ï÷éØjŽ*¦”¹¾¸{ºzhVš>Ë66"_!Q3’»-õÝvßOÙv¼Š‚©¯):‹ ÕV1¤¹@u~ëkþht65«¤H7?œX“P5Ÿ_ç?ž?|ã×ùS=Œ„[úæ 4äÖA—X%"Ú!HF#,Ï3Ú+žÅÚ„H2Ê.ý—Û#$6¥dߺ÷%ãÕÍæœO—É.Ÿ]ç@û?©ŸuÝîöK×Ú¦®ú2Ãåzmï—ðìQ–¿£õXW/Ý’¢0Áú%!L;ÎuÓ2Ù<¥;Ï6Ý°¼¼N°Ja•Kd?“"’Á#/‰•´&¦¯‘ЙŽhq9"ºT"Õ#/+èAá©…¤©˜¥q„¬©æŸö‰µ?·éf†jBóÌÏë#,‘!S[1׈0µÿ€~½ˆÌPZbòÔ@U‹‰®RcKÖõ`§v¬ã\XÏSô\Îf»Pº›–ô#,DÈRHè2Ñm€ì»•¹#$þv€¬FÍ`z04‚:åsx@â¤hT?Ò›üƒöoªÆÙ› $AfWÈXl^«~)úô_Þjv¥Q‚±FH+üœ"þézÔ12É'C£TåR°_àÓüœÚíýŽ ¬ß#÷}Ü¿œÓŸo³W:õìçƒ ýÇðT–‹%¤´‹4ãS5ÙÛÙ’ÚhWWï¾w½ùO—÷(´sÁ`ûOÿ°ß΃϶uÎöÓùãS—¯œ KÉPÜü\ÜVÜB­ñ¿Zß›ÛYŒ” ¦XC™ïf!ˆÈ(µó]<€3£ß¤1:wq»hi"m$,ÑTh($0á€ÀyŠ#´2;Û䂾÷%þQÜÉêPÒÈ(¢°‡c0…2„Š¿`üx†ì†SfBJAX)úx9Æ$ˆÝWËÈôOgž-‚3‚ƒË¡¤´õ¨d% pNãµTÓ€WùŠ&Rüìfšìç0x鈶Ø4 Óz<üQŠ^;ê™WC$‡s€þïàìÁòé¾dãÉÍoö Mº&Y&\»¦0÷å¯2m“|Ó‚"¤ppÑßíãñ“Á¿´·«üƒÞErØl~‚üºÎA&÷E›`¶€{gøñž þÆØ®®­ÿ$í„Å_X)„=‰­ìz Šf8g:³ÁŽaË#,覗Ø&´6_¬ž²áÊu¬GsÙÖ6—wÌ)¤»¿6¼’)iíÙ•eøÊxæÜö°óÄT¦èÅXÙ÷xUüÒ{ Ä\3ˆï@Ïèk¸(˜ªØPTïã°…äðDçG½#/@<0G{BŽ£|þxùdþ—zΖ ˜øBnÿoöv”„tm9þjP»=R‰7@gòüíÕòëlŽå爵Òy£º¹öˆ ßöC´r¾R}W —˜'9£§×$›}­!!«Øh~Y}:8“E®HòÚ¼#æl¿Ü1goåÔu â÷k‘@¢mµÊ¡U—°6öÈ|0>:(õBî›±lMÜ,©š¬áÆöÆÛ#/J#$øh¨1@»–S{à=N¹QG?7ì‚õèßËæzn¥ƒ&¹FÍXôݽâ6hëq#$—!É*9W¦ê¢#,îˆÊ9Ÿ9p“¨+ïíø5ªò;ÐwBEGÌYgi…@ÍÓúž%½Ñ?Lþ-ý$(èãr‰ Ü¢NûJq}ß­}<…°YŽýàê]‹˜rk¿\8íçÓoSµGø²F^©ÙwÝiXYzÚ%Òz²XêþËÕ7V÷ý-<%-5uùÈj#,Ü2UFf±/k¯Ö;tN®É~‡Ž±îe±»10(7VlÇ-*™ºßEÏp´ÑÔ|ËÐphÔ¼[•¢h)Äë9tÎ&x#]_ᶺgÕðÉxž1#,ëZLÞ&Ì©sŒì§>57™Ö%û¦œ É®z 5¶ †”{ö}/\\_G–H½c¤â4Eû“þÚ5Úù6o‹ÖóQr×KålÊ\å¬P ¾E“ÜGr¯½·çÇn8Å&ðà9;¹ˆnBèîní²Äö@þ'^D.™~™ÂešlËËQª‡MðUÊ|woØWÐyÓJJ”bh©š0ªCj#/#œhÖy'-zjnê¼+Hgu¨•G.,7$ôQ[)>é·BˆjÇ•ïýÃù¿ƒãçî”ý¨oËÍò¨»ôËÕ—tŠŒ­ÙÚN³Gt5’憥p‹kX3ú‹öb#ôMðƇÆ@Â$v>Wß9=fîù½êƒ¬‹°±¥D¤ÞÕe‰‚©è ƒá÷ß&’ß0²G+a/Ów9×O¨Tg¬Ù˜z‡úÛõ§d¿Ï}=Ê|Öys‡gûD_ŠíNï>xD„›ò@ÂÀìZ0¼–é6êQ-9ú­¶bêy?MÑ¥Ënª2 y”#/@óJÀvÄòÇŒÕ}Z̶M¹‘íÏ(?j-âQ£rŽw¨~Mû6€;?èÍ@ú“ó~„êí…-ïTwòóÇdEÂ^î›ávñ·×Ïm¡ˆÀþ;|DhÛ2ç˜Þ½ B!z¢ö”ÌýoMðAõ1žï’›Ë"ýZ‚æ€ã™ ¹ÓИ»tÆ6Jp2O»‘^i„N¨qaHB›8|À‡ùÜq9ðÄëóÖ"oåZe¾Æ$T¨A±()Š›~!ëÝÇo‚q+#,»çœIïš–çiZ~Raæ>ÄÙ5ì2}ø:²E`/xçìïés;hL˜óN%Ÿ"]¨¦b@6B÷ ~ÖZC‡o;0V»Ã°¬žuê͸.áe‡¦fB]ÃÓv’ªfkŽgÆÞ¹:ëf"Q_gêƒù6‰c9vðˆ·jhv‘1³ø8IÛÕ–4”‚‘u3#/±5"çž½š²ŠÄi¡°’¡9q…ˆÝÏQØhHÉT‹Úܘ]VHòçˆ/^Ž‰Š¸&ýr6-i’b:CO#,AÍ : ‘‰Š„†_§5?ƒögBYš;‹(°Oaï,‡ãý_÷YîMÇÕìã§òþ ,,#$‚†APæÿW‘î¿üôr8'ÔZaøÅQ9ß÷ýÞž£~™™œJ_ê€Þ^vÂ¥}Þûu8çDL™AÀµIùký}×?¯ö ÿ/ô~çÈn ÿ”|Ô9ûQŒ[þýl¿l’QqñL1#Fƒù²k]˜»S¬Ù@àVÝÄÈ5q?pšµbj#/vfÄ]¹´ÜQi )1B#ó:Ó÷Ùw^sc™Ð©Tjê1ÊÄ’_ª#[™´ƒ€&ÚôunµÝW€x>ëS¯2èfý#$Ä´v¼†±àMíÁºã²·EW¡6bN¯úíáÜÜ;ù8 ØÓïì½;Ö©R‚¥Þé iUÐ5™æfCS+fY±Þpþó`/HŒAƒÒ©ZªU¢›É5§fC{æÛp”#Xì7óa¦Ý°”'øgø¾Ï»kö!sC@,,©„’h–eï;§.>‘V!åùÏ9£«¨×møÊ)–Ö11;üŒˆnØM‡]M°ªÐ¤òÄ4Ø’µ‘Ä\ç\MPspëöŒ÷Å*„MTâÉgWåÁÜ8I† 8Œ4€@Æ°Ä B1ˆAgM@;H'0|Œ¤3À‘Ú4®úlnÂ>°Î!b+Q™aiM¥öÓzØÔ½Û†TH#ÇX3ÏÕ¡ÓÕXH •„8m¶y»I5nèegõÏkäxÖGãV,€éÝ臺?By÷s5“±rü}ýWº[“÷Â0õðÕ¨qúcö»»×Qfz,îÜ À#,8• B@ñl!c‘JVDVœ4¢ÖH65h.­1¶L´Jˆ$#,­D2ã5?0l¼º¿±—îʺÚî[‰6Õý÷mÉ‘y_¿ü?Ñö·´³Yš#,¢Åý~÷ºÂò±µŸ¿çCMçDuÕüwO5„ü?´å´*IóÜŒø¢1®í»6Üò„‡0È–×å?J¶ ºÚ ŒÎÜuw8€I¶j‘#/ž<ŒBþ²ý߯avìe.vI0„&Ëmš3ô)¹5Þ™·kr5QƒCg`Òðíõ¹€‹ê|23Žfµ¨ªˆ<ÍsÅ'wÆ«Ö8¡÷€C·#Å^¯•ß5JY,mMš¦bÍI±°ŒC´¸¼™7T™v‘YÉÈÁÖžãq)¯—ªK[ª3‰«Žhˆôz‹õ½¦Tuö‰sQ‰¨¡´†µêëe+Ô\›i\¤ë#,ág€`ðu¡Ä¡W"åEÚ9ç±Q‹åÊKè~Íe\ºaðÍzàî"i$-ÚÝœ3häï/á߶Å^W"[ ºí(IsÙêÞ…Îo4†±µÎÞPÐÚ’ñ!|0Þ‡ï5Jn˜Bfa㈌vö#,·ü"€Þ@I¹²¬’K`%¸n¨ Gœ±@PIúºÑ»#í0Lÿ«C§ê ’ø"Š}›•êz2ø³ -…$˜§ú#0f¥·—IšËúŸy”Ì“N§ôCHôçíŠ3ßP}wvÙ.•‰ž#¤'¢ ´‰—ÔOBðÈ9ñ„;Hvˆ"GôΫýHþD ˆÈ°8^ʈ%|8®+ÕSþ‚fÜ® ¬Ž›NßKä4Õ®Hc‘¦vvöe©´­%!×á¬0t¼ôÝâIæÖ- ®¹r#$ØŒ³d;éšÓÂC(åýOAôjŠ…=Š°eA >^ÿ{ÓŠyw¸+ñ#/OÃ×cý°ûÿÜÏúߎ’Ö?áÿ#,11õÖ³^u»Ïâu!D$ )~xHk~?ËjÔüu=K©P$1a2?|U”vvyøpô%P×æ@‡UŸ¼‹ì9‚Óù‡ÏÌ>’$&©m2U)··uüpZHÅD"S¿^!(Üã("—<„„;Ø'¨©!%-zÅÃ+ÒQå`ä>å?Ç$Kµ@©¢Ò(øk¤ žOÞÚÀxXã`ò¼N·Ç±ÿb®9^I!5‡¤:E¨îbUCPù@;?P¤D™wFÄ…²\WUQús=$$ˆ"9ê—) >¸±Š–LÑÔ¤Cj¦àæbÜ žÊCaDDÄ5,Ÿ üƒÔ¬éz}¦”l‘-hF/<ï½ê×Õ‹¢L>.TíN#/hRŠÈH k.m`eÓÌ€ÿkdEººûMðñ•‰û¬}¡Är5ÁY³|„\¤‘9ªÔ;¢×Í…I×âÄY‰9 ÁÒdu²#ó§Õ 2eOy#/Ž#$ ×´”è 7¦»ÙpŒ_küŒ…rŸ=«Ô蕃ͼ@mËN:ôÿˆEô@]2CÂ#$°V HŽ{:L^J ªí€È¡PI#$ ƒ€BGÖâ;Hà Aš"") ˆ¬HŠ4@1"¨Ä`¦óÄ0ôqI=VåmÖKŒÁQ£ÑÆJ>,(FÚZ¡d¤ø#$…em®^)Øj°ÖÒ0i1™ €Iˆ‡BÅ…‘Æêóy%2¿†kÔ"ñ¯EJI1oWvñé¶æõ7©¹®Ä£wv‚J€Ú#ÿE©VF ÓrF7 F£2VWvŽI|ºuº^r{ø«Q†EGþl: ·2ƒŸ¼ØB,$ŒQ‘XPI÷˜ÁÔ}n0cD²¥œü$OX+Àö¾Aà/†7òû—öèóûÉÝÈF’ç}TAìde±§¯ƒg^ÒüÓw<÷4ÅŒ»*Ȉs u ½5‡ $`òXÀwh.Ѧyg t>µ6ç–LÁü€èIo$Y–‰­¿ÕìDÓ§¢×î;om#$q`¢™Å¨Q‘'eÙ##$`H³?§‰•6шô÷aÈKv#$'¤hØUHîjÍey诬·§#g7ßDš˜)—‰’É8°0!lyW8Â&̆Mup÷%$É„‘Ê4D¢RÚí¥MÎf4°¤¸Ø . —èb€RÄ_¢#,ÆànšXo…7k‡½ÿ)RGøB‚¤Y’}¼ÆÜ.z½·D´ yqm(:Ç«Æ'è #,»A#,ê¾êµX;]׶Itî ½lëÝi!,ñímaúƒSšÆ‹ÞûŽÜü½ôÉúzó©0Ç…/Bw¨ˆ–K?HÿÙþ9:$­›£è|ÄïGŸšãœJ²AÚ þy˜–)×FX-Ž£…Dª›'@•Ö~Wëõò(„%Tª”Rvuý!Óro<( ”u šÓÓI¥/g)äâªõ@$P WÝ!Ú ,Í‘‰_5NHò1•ôœä³J°æ[:¡æ„µ Óàj$(/SÒ‰Ç辰¶&ÁŸmüÕžŘ̑µÕr³`Â#/;¼wcº¶†G»² ¥‘”ĨñKDt ´èI"Íb­¶ÉV‹d¢6jÆ’l¢JŒV++-«M²ZIkÒV²2£M™•ZZÚU¶f­‹kòßV$ß>3…¾©Rq‡#,b'Š  ‚‰F@^`{`€oq`JÔðt¦½c7æµÛd[ªÁù°&Ðçånd(`<46:â¨æ¢#,C#š@c€à‡Z*Ë"—슡‚°rb2œÛÃâ|©+âö…öË¡$‰À„ Ó-š&Þ ¤M:Wʦ憒Œ‹@À47 ‹ä çX2ÉW‡)ÓjÝw§®*ˆ»6ªP Z(ìxGߨN{ÒuqUC&šÝ¨$[j]8l JºU‚ôÀ¦Þ»(¾žñãƃL`é*F"¡R¢›ulÝL@T HËh„3ÂtBE ÁP‰'H’åcjŠÕ͹²W+r™°¥L¢©˜5%lTZj"‚€ˆ^gÝ<Á ‡csLšÈ#$ß#$„@ÅTìE]xßV÷ǘü¯}¾gÙíÂÜi¦ÒÒ˜8\"mø#$DÍäAß^Gx ÷]ŠH#ú ‰#$ð¢¤7Ú{ä=gæíÿÝòýŸ£þ§÷ë(>S~ê'Æ0Igwž ¼T)Š¨ªñ1¢#$’Ý•ÁÒh„h¦D"°¢#åUPÄø/{í;|øØÅt‰¤¨S›JŠçüAqˆÿ!5üóÎê)_[Kìë(¼É#"Z õÀç7àÐ$¼V-ÕÜ º0ÆjC¼Kÿr¡ÙÚøô?À&V~T"ì`dCc˜ƒ"(e»Öw ‰§ ;vä>jtmÔBœÃøÞ^P/“ »PÔ÷X ’§Ùl#/“’Ì€þÓ8GIÂk l€(2‚hÒ:#4œÞ)Ì÷ô9|¨ë`ºö”¸¦sz&(ÇþLy¨*_]‡_¯â5 ab’h×½Ñéé}›Ÿ¾¼!Ø¿ãwfÜÞú¨w[#/=÷l?FSÀ¬4ù8|^+¯×ïÑÐ*¨ƒÂ`ý²À ”Œ>·†D=ÇÒFWxч>ž“|lND-¾0M‰Üu§$Îâœ*•Bz 9 ø¯í›»5gl ±Nƒ .[O9´/¶LV8¸æcbÖ¹s²È {„"ÀHD{JJŠ‡¨|CÆŽðí}Â.y!ï¥<ÇÇ´î­I%úú¨OU‚%Çý£úýr†”…¬¦ªŠƒJ5ùj»¡â8¦M²®î×r…%‰5÷ÿ'òwQÀPL• b±`ÑH«šÈ&P P"X€ó²¤ÓéÏv^ÕúH#,ښܣ#$ôÖdÝ×|ù9<]B%²øÙ=ŸáÊAÆù¹ëc‚ñÇ+ì€#%KMà‚å.ð~\ùÖú áDˆv‡èuÇ!XÛ¡X:&+&ÄÁ¡MìÕ„Äå…“i‰lc¦CMô£r{ \t@s•k£»ÑÇKn:v®Ë§~:ÇmsÊáÎ8âŒvÕ˜èY{³HÛ­²T&¹Gnl÷×=k _ÏM‹£¯æhz:®ª0l6·Kê.¾\ñ팩l7<ã™ z àMÞ[ôÜëg^M³µ›W@g#,ñØ+ÕÜìØÁ»ôű©·|ûâÔíF&hŽÕ»(tØ·ýË¿²¿g_Z#/A r"Œ â+‹™›D)”_Dz]¶B|¬CCGÃá‰Í‡^›Ï¯v&Cu<à†Lh׿¹÷8×»¼˜öÃ>övÂãÍÇ…åÛ`FÀšzŽÒwHè[ÈT÷—ßSPKëThVB¥(ã—éèsçáß݇ØÚVŽ{s!MgÀ¯\úÈb/À:ƒ°àeŠ#$Œà´5÷\c½€ #$nEcFH<„$"ëËC>pÁ‹lßØ¡ùÁS’'+ä4è»ADDšT oÞJ-gjŠ$|0k1ÙPñ3@cµÀÏh1E°ˆcãn3¿‘ãsô}_ó2Îú7»un£6­í{Ã;›ÄœÈÕ&„Kí¸-y²^Ìù%­ŸµÐ߯}zw áöir¡sD鿈æ»#,f$MÜç²€ƒ-Ž|ŽB:£‰ òg#/4p‘×–ª¥KD†C³³Æ}|÷É8™˜4¢‘O¥×ŠÈŒŽÍ4VK*›ªÝXÄ÷û÷1è{@R^ܙȂ!† H±’jxçOuz™íéÛ§HlmÚ]Šj&:Æ#/½:}ƒB#$eHÊ;oÞÉÓ^Pz{~†5¶#,èýÌ’ì0.ÂŽs˲&œy#,ª†k×°ÜëÖvéŸÔ|T×Ù ÓÙ¢¤d¡Ê‡)ZRIÖ¦tÔÔ£ô÷õdGƒ]IqB'}º_ |ã±y˜õN•¯&lyo–NôS5@1ÁÁäÉñúïÀ„FE4øïÇÕ×µzeQ ¾A×N¿f-jÚ hœ@ïï yƒÊ±œ¥0KÈç`±j¤I¥iUº«˜¥‘¡›%µÒæÊNêêlä\š6ÔÒÚ‹ÝHÅ#Pˆ+#0+–#/Œ…¡*R`B…¤¦’.£[w#‚â6Qš‹‡n¼BÉe#$HB+ Ïz­ó/kèÑhjkÌ%Y• *H›Êv)¸8—l)³DÃ:Êןg#ŒúsøÇÛ[_³ë«öîOÃÅ¢R¢ŠRY@6’ý…t°2k6ß±uÞÂOeŽˆg®„#$¨‚#$ÆÙCÚ#,ê„lü ú,ûžÔïu«¤z?t]™’ /®¦2‰Q[ØãW:à 4óI¢FÎÚ/caÍh¦1ÁP¡Sš®Á ÇUjÛ Ão©E=?„é„mvïž Oj+M#³P™™Êü°­0#/‚yÃiR5Ü+'°#/¬::ÏfyéÃaã°Nä‚qB{ð;äœ;çÅ#¢*²mck*ˆ,˜R‚ˆ€¢"T¤dP!r7H[,¤ˆhZT"XR‹³v“š¶Šf©àC°úèÏ‚À(¸q9€È’HµE(€’!Òéí¦s­abÛEx4W÷èßÕÙ9¯.y$&;ùƒ¯:÷Ö¶©Ò›> ?KuUÉÔñáy¥}®ïÄ>#/`ëÆ"€^%Jn~M)Œóš;ÌAJýRM¥,m¶&mUUO™ì0{ ˜IˆUíÀVýîgõV®QÇ}¬¼„*Ôz mÅÖÕ C!Dgr0< Q.Gc¿|Rí¤àÙ •Óá€0“#$‹D…Rhj±‚)ëo]D€ŠÐ¾OUBHp׿¿ŸÛÜø¿L(:­È×#,•G¬ú»{xó*¼ÀÝÐÝ%¦(¢?]¾˜älÈh›X±,´P‰s<Ìt¡‰«Î®šåSTÎi¡r·Ó¡Ë ª mœí0ï´ÉÁ'¸hL0ú„­èÇàh”q·S¯Ma†`:µ‚‡tÚ·ˆ>ˆèÇÂ÷µàp„-Ý#/H5AH´²—|Ë: üÚ@VF#,à»o–kQ;Û>]úmtM¤qü:vÃ,1gb†ÚN¿&RI$7ØM£»³½W@ãŽÈ·#,&Òì(¼x„„ !°×Ž¥[ªØl‰~¾b@dŽ“pID›h€N‰@x7 f j2B„º+N„¹Ë (°È îHÈ‹üÞì¯gó›9îU hÀozã î6—°FZƒK«¡Y()¨ìÑ ÚE]M0N6Ĉs`2B5¬¸˜hiƒ"a‚„ ‹=–´G åÆÙ†¡3„ܱ’´—ÌxØ´ÖVé|<¼Þ©·­µn¤i5Êi0K¡ "R#, ±FÑÇ–íÙöíuv^Ü^DõÃÓpJûiLw²HS°É¸œ#,a`Mú| *1{9d_Qµ×tFŽ­ͧÕñ:´—JlÚ;€ÿ02„x2w&usà[ûO(I¡,‹7³ßÙÔm=MÏÄ’ýäµ’ý™ˆƒ~šÉ¹ülpkÚÅÚjem’x¶vô~-í)¥b{|4ðž¾Ä}Bâ½Ü#,#,[ÒÁ×½’ýõÎÞÝë Š4åÔØ•!ÇrÇðég”N;8‡#/0ZMŠ(R¨”NOËÐÿLŠ@ˆÑTèk=þ_^§uö&.ÜÏ‘kÖ2¥Ÿcô¯ÃyOW¼ç¨¸|ý¡Ý¾D¶Zˆ'£i·.†9Yðæ4€Ø1#$§#/Çi¯èóê'}Í-«Qc­¢†@%Q,D(Qï#,"Äç‚ГòõÒ’‡cqÁ“sF÷0nR£dºÆ•Ìhé’Hæ&š4! ¤“B¦——L ðiÙš›,#$!3#$”ó˜,(ÖwS<é½m\ÅÔ´ÓT’¾ZúcLAS#,º¸·GäÅ ¼Ôž%ÇRJôÉ·ÒwXU :É–c7ãweüIÚŠ(AÏ «¦k³L9ä>øm5F½rùSÚã‹w4¾xz8º:ÄòTF/åp8™hþë×ÔEÏŠOã*ä4ÈðÏØh¦•Mµ2½jkÜù?×äÀd!$Fç|í°„Þ4ÏEo·V¿mA%*U¯Ä¹âÛˆ,#/ÑkQmx¨ÕÊÚØÛkQ­«•·5±m´mWKK­Âë>­Ï´¸œˆ_½ÂÂÅêŽru›-Þ«[¤Î úÓ,oS¸f°bÖtlý$úŸÈy¤Öµø$Ê$‘¡$™3)šV™fIJM1Iª-&jÐêL%­!ƒMJ)¢%#/+K÷íÌ2kI‹$¢S+f…2bf™’3ª4Ä¥Céî¢#i,Š‰LRJK(aª ’ƒQiQ¢ˆ&S£4c&JÓÖ6BeA’¦ ÊTf ÓA¦m1%4Ai£¸w$ÞlöÔâ<€¬¥ûB¤!lö¶ø°LƒÞüÙZª¾¦0…»1¯óæ̈þ±Ùüâœ$TnŸÊðÃ9ÙÖ‰†ús†Áƒ³q$¶˜K#,û·m”$L ¦Qmý¥pÄ0#é‘Ç¡¨:÷w›EF£?=¡‰}æÍ6apí´ÛD¹cb‡ƒ‘‚Î#¬N«§nk—õFöqпÈËêÝ{›žŒkùÒÓÃ-Òo‚<ä(y™Áí#,¨¹¿ðýõa‚;S.y˜6åŠK˜ÌO‹}HôÍÕRGàóx¯™¹Z붖º5¶R!M wŽŸK€%:LŠ;eòÉVqsž\·iˆ£¬Ê%x4ûmÁöãÇŽH‰ˆÌwŽ nk‹“ÆK –Œåñá×gÿü€¬í6pbV´Ÿ±­]RKm7ÓÑ×#,í8~æQ‡­ž-wd†*t*. Éns¸ˆ•ÐP;;åHÛ;ª°¾¶[a:y—#Xc~Mö˜;t°Í>ɇ#Kßóúë…ïü';IÑ!RC,7ÑÝRoG°Cíô\C¬í×óéôã¬Ãø­eúúPnƒñxÚ{ÕK±(Ñ;^{²“Ñž§ ü“@JÕäTŸg—;ú܉l‚Š}ù ¶ ¤w¤8ø3xï#,vÙWfŠ’¾eŽà2j$Š£›«‘Œ%œ¸jLˆg’“¡´Ô~'|ÔÔJ=•Ô‡nœÑ]¿º$ª PÞVàÐm:rí£Žý¦ÙÛóÎuÂHDôɯ¿3ƒ%Ÿî5)º‰¶DžO©¢:25Œ+jF8ÞVe¼ÐÛ2jŠPƒË̦ –.šposY§ôq™†ò¹öFÌXÜÔn&s¨óPÓ2ÖÛ4òóc4ÎF¥Ð²CÄÑ£QEMJ5)‹ŒÖ±,¡ÂÛK,™…6®¬š‡[|fçúþ02!ðnÐ6#,ÂΩª²æÑóÄïLqåÇŽ™Ù !¯6teÝ*ÇV#/烨i¡Ñ72Ò;!÷67¶ŒLªL¾t“ÑŸùkhÝF9pë¶À…ø×+iâ5­zY̳Ú~s‡[i¦¤¡c»“Xtµ¾Ø‚æçk”G#$í,íçÖšišºÉWêù6RMªhÅ£ØZMDxé‡== ïYÛ0gʈˆŽ4åç‰2˨·¢%fïlÖg&qz1]:Þ·Œèt“:Óº¶6´=V_ìÙ²„o‰ã×mcXqÁs[¶Ä'ÜFtQ úÜ:IÒ{À”˜KAšÔj§=1㱡Á$š59Œöâ¸:¶­L±¼ow4Ö(qÏ:ß/Žq˜nWd/g¨J‡n2NŸaî663#,G–ø#,cv¸ÉCëÅÔp÷»TQD—¥I@(L˜„™1Žc¬!1áæ[‡#,m&¨Æ3f‡ÛZ¾p<ÂZvÐnÚÄ°ÄŒÇ †Ýà€é`×B&¸2 ZàÉ2D¼ÚCȹiawPPe†#/0¨á¨qL,}´Ô)«)„‹I:m*—ò¬*ra‰EJÅXVù¸Š²o‡}Õm{#)!L±Š1ª¸ ØÙž¼çMaæü:ÙÍøåÜÉ_Tòˤ²¾uF‡Zåͧ)8ÇbÚcLÌÜ¡ Æ´±:Ã)ŠI¸˜+/QŽ’P™6ûDÄ>id›cRNL¼Ü¢îâÊ7L:àêçµÁÓT䱺”׬›Uà58‰³´&#"B\˜7è$i¯ŒÊuÖ%HjæâÞÈTÓHªÞʧd\:Òvfk¬.C-¢,®Üâ’7„£2Á‡ÙÊ#,)„FžyM’aàÚ±L -šTHlúiv3ss4tÓ•§Ó¶ WCBi”´†ŠuMˆ¥’Œ)‘C&Ŧy¡p9ó©3…jR~»4=¸ÍÃ#/Y¬ŽÛëEÎ&)Ä+æað®ì¦fƒC\Ć룻ßÛTcH±ãvšLºsîÉp‘†üÑš¶Ž°nš“U|øÃIãZã±Ìß`pÖãÛXÜŒvqʤ! e“â"•¼ M4–Ø.*OfÊL‰‡"ZŒ-íð,.$º˜På8¹™˜ÄÄÞg}C®Nwk_#$Öò,®až\´ÃãŠk(µpžG†SbŠ©)(ÆùØn»#¡›owšËYª=hÆæYˆ”G“Ž‹z×LTLT<øùkã—Ìél‡68'-#$ëÑŒQ âÔ6ðFëcCìš°œz|íJÉ[8Œê#,9|`5Y0}ÞX®ŽÄ™+ 9€IŠ9gVZMèÈÍÜ …kYªZlí œVx#,Nz#/#,2¿NL$13£ŒPiIÛ+] g‹›w{á=ng|ô2æY ¨ù"4ê@ACñb Vf@°ÚjuLrî+˜ÂoÄ…%êš¡L"†RP¤…¤ ¬#/e±Iu!ž ÕÑ%3ŽI89;#/#GH#$8“,Œcm„‘€ÆÍ¥×Âñøk˜[.UŽ±¥¬Žÿ´©3´›BDv ‡JíèlËRQ]+y¦—"€9 aÔ4ë8†æy¬r¡˜%„6(j¥³„¶"#,.¸ó‘æ!¶ÎÛï"†Bˆp5¬É™¥Ìkcp²>¹—­‹¬%p%R‘êå0ÌDŒi+ fç†èd(p8è; `Èéˆá ŽÄp‚UC<Î;&ŒÐ ´ÌÔéFzñêÉ0F ‰†Ìnéhg4g.3ho$#,†DN%½ C0é FÃ9²4SlÁdωPBI¨#ƒPÔaÂL#/f³iÖÜÈu"èj×3^"b¶tKFÎL¨èˆ…¡ \¾1tÞï‘&€]"ça§Y¨Ì2 ]u8‹|î^áp T:C°=#/è°GˆNfŒ™«5mýüµÖÕüϦëw#,¨@DÕLÁÜ̯¥MˆšŠµ)`5þ\~]áðäà‚b½¥UÀÑV0Á-J©kô÷_Mòæ1 † 8‚##$"§ɲE'êÕ÷›†¥5o‚W[ªì`¨0ÖiЕê#$ƒ»-=Yk8Ÿ2[@™ P‡é…‚IïNÙUI‡Ã>”þw¸ú.„÷ùg•Ù{ÎçRÎZ\ܹJf´o7~²Û¥Ø‹:Âó®_m®P«4‹Íº…„Xó#/Ä>ÐGr¤uÌbt6T½2KÍŽ& Ì»’ÀÄCÈFðØ1bÄêzN¤uä]\䈙¤ë#,õè#$Æ{H¿c‚4rp?Ö‡îtB£É)$‚F;à„!ýöuØU#$(i¡Ææù¯™m~4Ëm¤Þ¥%”3Q#/"ðòŠPÙP9[L¨L) õøõ¤LDÀ5=Y•!&tƒk!kš„àjÊ¡ŒZ\aî÷x©LPð_¢qn¦Î_“µWä#$oÓµe–«ç\¿yS—WwUÙn»³.nºnØ-sd¯å¯5<¿{wdHç }æ£Õ½AßÔî, üŠì(Ì|ÇUGèÆLK¿‘ý&J-Ðv¸¿6À¼#,Þ|=ìqØ<ò/ˆ±'Ü3f•¤Åð#`ÉbR#$¥ÕBµmM¤(Þ.,¡xß ŒÜ­ƒFŒh2!M1X·¨•Rš0rpÁ.]¬é2¤\‹ñ‚b‚Çwê\12H,ëhA(†¡£°ü™ ~Ò!¨=kñ¿‡ÞaG“Á Fö5¶±·M w¿5üN¿ªkì[jm )+Ʊ£Q[FÔIDLMŒÓ2Ѩ(¶ÆÁ_?ÇV]:íà›½fÖj¨#/WR›õôî\SÅwGC²#$š;= N‰"O­bMxZ ²Xˆ‘ˆÚa &Àˆ’"µ¤rˆ¶Ð*Ÿg áiŽó·¹ëÑÐ 0 cÔó¢ÒwL—ù-`9— GœÍ Ø;!z±Q¢/×j,EIr>Ý%Y0¯Èºî @;(96ض›pÌ®²¤ÓE3Pa“ -ÂGJ ‰ÅZLic­$YÄ÷›ŒÆ„B»&Ã&#$Ä%¤/B°‹fR–@l@ÓE`›Œ+K†³D#0þ“Œ¤LØÇq]Ê„V!Îo|"üŽ´´`GÖF˜šhxà›rFƒ‰’´˜0#/¯ÕK{÷ÌoRCŠf)wß„<ÉÚãšÌ´ kœæ¨dÞÓE¸ï4†B«ØÈ4ÇÓ¿nÚá.ˆåÚdƒ’#•u.ª‡!6Ê6â%‰Ø[¢µ¯GIhHCZ0 ´‘4àa#/^pí‰rÂö)„¼#$‘ð`ºD²b+ªFiç<-‡åäð‰Øvø”Ü¢ì’*ÈBˆUŠX.”¥Å¼bÙù†’]p.´Ÿ˜€ZÈ!QY/}€ÙC $@39$°GÏ#$3^^UV©Æaáåm7Ó3ÃF]œm‡6±Ò~R¢°kLü·p£ˆ7Ò.Fjk“‚¶ˆÈÂd\}™GÃ×\™ò)M9"˜H_S—Úmé#,øeDwφ%5†îÑtDiÞœ4ã©LR#/ZÅSÃ[Gjjh†©ql"¿§p’p‡C™Öf…P¨™Ûf‘¾"Nl°péÍÅ^¸ÀãF:›tØÞä#,ÍT„»‰ÁhðÑ9wå`ºwÜÚËA•¢ß2‚£ù´œ3L—[#9I1ÀíØ’Ýœ}=ˆ.Àƒ åp•Bj¬šz¸S€ÖÄröj×xWF(E!Zæ´ڇ.o. 6¥Û³#,kœð\fÑ`±„ç—x¸‡kÈDÔëi¤Y¾YÚ·¦4$ ²4(pïŠ2ªTšh"†ÚÅuu°Ä2©Í²Ð;ÆàHB,‰’&l`2&%É#,ÀäàÐ&xÉÀÕ„ *‚–BLP16ˆq›ðle %3$0 œ @A]ªƒ^]{…ˆ{gÁ¯¨‘#/ÿVdÏ’¹M8¤Qb{(=G÷+t Ãä@û¥˜}cþÎ ©>ø½ªˆ8KI®ÊvO;Ø.?ÐhîÄ™”z© KBùébìU¤½sã#/¦˜w]ÝÜ»–íôÖ¼kü[*¬›jÅ[Iµjü6¥¥£H>ïf0Áú™ƒÏçµ'w¹z—>(¸rþçÂ|Öò‡¯©ü 4µ¢—ÓŠâk|t¶u+W…þ@n.¬­…¨ê¬ÞÔrØr­$®E#,“{:iÃYÞ%lšeäʵS0:2¥KŠYk2k/y¶Òl¡´‚‡ßcR×­F(«¥(‰¡ÛÁf±‘EÓ)xšpxÖÞ6ÙGŹ›Çy& I-.é)„ Teæž]©ñ%íÓÃíÉJÅ4äD™æ\5&艹’èpŠDt7Û‡š¡vJ4c:Úo¡Æ:hÜO–yU6oÌI¤&1÷" Ú#,JwØOXéáÎ-â­6éÂQL°¬RŸ1I‹SvÌ“3#]ðç7jg=5fgIÖÛÅU#,7¾ oSi®k™É_3O¦R™Î>Ó;²cÛé Œ’d*MhÃ#,TáŽC KÊŠÖˆ{Ò©|&Å5µi‚ýŒþ,å#,©( …bˆÅ†ääcŒëVéJ°d@)‚À5˜±‚.+£d=vúFÕ.6–2*””‡I¸#/Ñ: 4,h`БKhƒPT”4 I$Y¹ YÉ.…*R«ˆD„Uüa„¬i"X/,»ïSù*£œv4,Õ#,ŠB@½T¦‘î*®Ðçl]šé±QÝÕéRµc,•2FáK èíƒ2‰­ÒÍ76èUÛWi5ƒt®ë®î)7Šå¯]®L´í<Ýw™W“bb•ºšÜ65Úh‘IY”ÿ›3"G(¦Ñ³Å{mÅ­¼le-¦U$„¤È›5±­5"™®¥®•¥”´É­,Êšª4ùµòóÂj-P`±S4Um ¬HŠ†âÞ¿#'ˆb¿LlhE¡4Ñ£à˜—`IˆPÀ€¡Q6[@‚—bQ€Q‘°X!¶+åØD<ÎÓÙ`ôå„ôŒ.‡cÓOÒ–œ1,¦a™«Úlùdú> €zBq9ÇÐQA}€Ÿ$ fX M¤Õ"h”7Lx®”ÒòÒÖá#$ÅRCGåg`“2TÔ±‡“U¦ÚN9¦*žGvtvFàè<Âõ&³#/TàŸcøX:˜·½*UR ¨”‚Yüô Z2"S ¨FV$¥×©Þ³í§‰Þžx‡8Ã%£÷hc»U‹}™9,m§é€jÒ#$AMi­K‘Ù˜ˆ<«…­L¦E| w$¤0‘ EhÒ·gêýÎíœu·kÒ<pïÖò«Ôh¹p¨îÙÓGY°üÉÌ_“-,ÎúKʨd"ä@EX—nr­ýÌ–srÆ™°- ²ód i`FÖÃÊ»¹ù¶Cd%GkÁŸ&}ŠçDîq në’r¹!œÎD¹\BÆ’¢«þ[[#,Ï[pM6ÂÔèOÆî¥ÙËB— ™É¦îä˜òH€DAˆ¤ @Wð|}_Q#/æ{³¡­¼“¿}”~¨¨gRŽ?àh`(TÛô•P 7ç™#$˜izvKQµÏî¨Õ’/aDÔ—·nª"d“xÖ×"ÊhšÉ1­æíZäÓiXÊ[I²‹HŠi–K)’•E1K-@¥ö®°¥«)˜lÚ1&ÑFÚ¦µMÓŠ6‘ª•ÝtÚ„¾®Öí^Ý»*b(2#/em¥­)­IkjhÆ¥Wî*®µó¹Ư~í’lŠ-cdµm²$‘6ËZܺÒѤʤš–ÛÏ;›i´ÙE0©«#,¶–ËI½­ª[c¨tVl·]yÜ’–ÔÉ¡®[«5I^ ¬Õâ»bS« o ®Æ+5mFHÿ|.núåêÍ9n<¯%`:1á·Œ²í+;(åxâ{ýýuèéžÑ’hgU¨*ð’Á\­v¯zª¹Myaa“6zùèú`º'„Ê]TRÖKEÑ:K@¬¶å‹ ¸C-tªŽB¤2ª#‚F `’ $€PžÝõ¹'U{­!­šVÍ6׺ڮ"£ î”ÀbBÍ%@ˆT]UBX]-¶*æƱª·}ΫW›L¦AÑQ3¦Âšl)E1R :¦ÕQdµ¥³Q³´™‰m"„£R“T¦ÛZmšfÖMl4¦ŠT¦ß¹C#/$ËQY¶% ”eiI#/46›e)¤MIš6f2ŒPXŒ4el¢›&I, “V-R•AQR›*R™*’´RU!‹$mJ%hµ›M !BJLX)2“ ¦I¦J–j¦ØƨŠ²$mE,LÚ“$‹+Z–k&MRKJm²ÊÚ’ÕkßU®íµ¥f¶›Ie©#,%½åµ®›6mjSUdµZ5^Í^löUsZõš¬[m¥-‚ÚV‘*´©VÚ5¯Ö‡_£ì+È7ºÃ}ÿ£fMͶGL’òåEÔJØõòc³'f쌴Óýõ4 €`ôš‡üS†2‰¡‹ß#,Åy—i½Á¦ÔSÇ*IRbx‡€RF½.m£œÔàœx…*P‚¥~]Å('~¬ šãŒ>‚7 B8ϾŒ5üù'àûÜ#/$S1é„ÉR‡Ûm;5Ç}à—®…]¦¥c{¶&)tÓÌ8.X9†êm‰Sõ#íô+ç/±’•n(4ªè~“.ÃBíq1Ô*LáPT_ã¨|ÛeI¡ý²=²7Þ¥|| ÏÃœáuæŒÙ‚öÞ YÎ#,Ü…$ój(°*¼n(ugK}φØõl£qGFù¬Öû ³]aPÌȵ¨|Ãu#evìX!öQ#,ÓßÖÛÛ´à"ÅH<»€#$bÛª0m¾xQ@R+¥rÐNd#/Èt(Ý“#$ž‚"2! Ö$êåKšð5ZÅsªåz±VbÂöNé}»4,ŠÀˆ.íÔy VŠ*J¡ ÜN²jçGM9:T¥5[W^• iô» è%?Zö{€@<óÓw‹Ýغú½±¼åìlyWVÎúS=¡¨4d€û8ÚÃÎuÀ“8 wüÿÌÉ`*ÍYÏ¡E#/e"ŸV.â?±¼µ)& m ,JÒþÏßkåªÖ÷+-Š1¶†VR@TbÑœÕDÐ1¬h†@‰‘„mZ#,xˆjI­ÔZáQ³IìñoMéh¼½úæy³‹Ý£C#,cŠ±¬Œ‚h¼°Š±³‡ƒݶ©g6&ؘ¡»Kq‹±Å,Teº!Œ4°ª©ét2`©jÐñH¤Â¦?Š¡HkŠFÝ´¹@„I[€ ÍÖÇ.q½J<BGàhÊQ¦ôÕhXÐôæ‚v -‡v¾”=äF”§:qHѪJÇ.2;p>0d'´‰§lzC¡R»={L²Rì}QèÒw#/äBH 7sRpäÓ·£z· ¡¨u=šd¦0-J0U¤ F$˜\/«²¶æ»R¶‹×£\åˆøòú‚â@'3¢¨ò±sný›nåõ}aÌ>Yµ–5&q?Niý->×ÝPcGâës¹$çL¼•·,ET4µæò8äÜ’°—¢v…ïP•š-Òdã©3¤)32ÀmdBÁ5érÍô’²¦TF#/߯zÁý97ƇçñzáïÞÇ„¨!Ÿj¤*ñÏX¥cçß0ÁøªÑ1ò,8™gè‚:16º0™±báX£Àúè¹´#/•ñã­tÂù_µ `à¥ó¡;P඙µœÅüó䘵 àü¾R¶+Úøsg8ÚKæxuåå4Í´mXÒLh 4Ô¤¤ñhòÔEd47 ¨ F2e4{&pp}lìqS¯=;+R¹ŒÎP"Ü 6¹dl¢ö#;§€õ‹]·Œy˜¢ Óm§…yzbzÊÁÌ:%ÑhÔ™8f^!˜, Øj"jÖ½+%šéZMûé:Ÿeûà‚ª‡§ û(•T½YB @œžY•qZò‘ïµ¾Õ3í x‰€Ð ’ ƒd -ê¡V)ÂQ48é1D=h «@ÒdPA È…¶»g«H†}·½äq%”@WS^#,†òd¿î4+ ðÈRÀ!€²ŒŠx£"TL$zÑa\ÕÄ McõøÂs‹IàrÂÕùïÎ3"1¢wSsDÁ¶×M„NÑ"I †Ï~^šØ;Š/ÏÅkÀ9!µ¸)5¸8–4Ò‹Ž#LFœ;"ešÝ´6ÄÎ6$L9°pK4#$1ÌÈwó •XŠ¾”R¯Oaz‹#$ñ=;NÝÖo+fy*wЙ¹çF|û Å"TX¥BR1š,!E@«Þo´³Ñ×E1&Œµ€Æ$‹,!IŠâã”È#N•Ú\/èÃü#$]» : ¸G[ÈØR#$œ£¦H…’4Šœ PEw`X¨2#/HÃ*¨ÈÆâÑ\ˆ^Èõ®ïƒŠœ¸ö´á—®ìg8ØHÆ›VBI‰­6‡¬;©¿§CgEñ®Bø÷ €WÅŽ¥ö÷Â^-h”‘SJ§]I³0"Æ#/Íè©tJŽÎøy®õÝÝt¼îÂ2žv¹ÍÄÀŽ+µ¹,Òçžu ñ¦éØ#I^Ùã'Ó~‡-F’ àEHvjDÕ|2Ú½‚=–Ù#,½2ã».ªÓ`:·°™l QQ׶^¤#/µâ[…â±j˜¦«XY!Æbq!gù~ße>“@ßJ8&ýþYtªïˆzo9z±<âWsÔ)±PN­í;1‡ zðDÞlÃ(ÇÇ-™& `ŒRA„ôì2Øé*ZüúZI¬€ªLÕ0U‘‡Ûù`Ðrw0K:|}Q#/F÷,0%à'—Š`™{.¶Ø‹Z^ºÕéËË—xº“o­»"fbBw¯+Ö«Ö®’Q›¶¶Žªø]¶½"تמ§‚3Û¼¥ã§vâ™*åÌRöJ^dCV(ÅiH@M6í××;ÒÚD9Š;b¾ÂêmîÓ5×›Êd>^Κp#$F ãÕÞ!¨ÕrO§wó’eJÖ‡3„1}ç}î¦Rg¿s%_–^—5øYÍš-¿uÓä¹||¯Jð~‡|:´jɵVFaþ´`¬*™23a¹$ž*+{ªi£h™Ej¹FU4Òi©]t\ۡɉ,ŠÅ´j¿mÌbÄVŠ×Æ”U^—¥êmkÆåYfß¿ýñ¶É¶´Û+V½*ÝrttŠ7ĸeÀ ®h 'kåŠг)ðÆ–.»YœHe´"„¶JJˆPÉB7&®r°„2ý-„Øo!%#$8w,´„HÂù-ሪÃ0 ¡‚±Å!ªÂ7DÀšÛ—§#Wg8hj„önI` læÓ3s®õÁ=²QPÑEÿ8GBÒ”NÄÝœ´¦#$m°©ùU*ŒµVzPT*éd“W˜fTp9°Ë zœ :µ8}ÞŠ1CøvT*5¨¤H•E,‹2*4›EQ©Û[nª×Í_OÓ›^âldˆÊê²àÌi“8²Èà¹{ªë~]°±[TyÅP"¡iÄ1²ƒoE½óãÁõ†çq8`ZÑAœõ²#,Æ¡@ ˆ(À°,ä]ÎàÒ¯—P†¬3Ëßû°ÀEØçP\ ‘m € 9{>¼0PhÅ#/€‚Qþˆš×aÅ\M¾W>»õnlçpñTe†áà(‹#$"BDGåÄ4÷ëÕI#,`—ÄÑÃùñ>Ä~]ûÏÛýÙ¸üE÷ÜäÏcK»>[^E¬n»&ß­¡=Ň wuŒðºy‚¼U¡Í?—ÞG0P­ñÇø"$„<ïã¬Ë‹ÛÕ#,öúuÃ1®ýŠ´ÎXýÞÝÃxsÄ„#ñ ʽÌÖ[¡MQMˆ> r;•ú=˜EþsµpëôyTI$@S°€)*”¨Š…Uda¢¥A#$dP!’;‘±f…â•‘ ‚È."+Lf¸aî¾’'v5™—îCæãqƒ2WF#/Ŧ’Å‚œ £d/Ç=bèp#,=Ç4æ|ì|Þµ?»`ñÖ¬²}cÉ ÄØžiìJ3:àï4G…œJÇúAÝÈ8É$ $ê % v_‰l‡q„}ì–©-%"¸iyHvý}‰óÌ.ñJ£Ÿ—³Ï—K©A…\:“?1Ô€g’ó>'¤ÅuØ{jHÝfï)@PvA›Kòf ”ÔT„5Âã§u”ûÔ‰ÚE@ëÄ„‘˜sô|y OÆ$¬… u¤7©ôµ¦Öæi þÂý®¨hÃ5P**…Q3ü·n)¢‰– ^J¤…2–#$’Çv#h#/ì þL hþö^ª©uª°¥I#/muX©"à.º…Uã–w}r$´ÆÛM’¹Û:g:F0¶ 0#BÌ £&D®’f²Úâo*QMQošR\!„$Z*SS ØÄ[U›Ê#,1´61™Y+B)„ÔÆ6«]ZŒ`”im{®U»ãÚ¹Z1mìÚèïj#/³–”y1†&&ùe5k¤Hƃ{µÍ´[pƽ›Æɵx±·¿®B1ŒŒŒç+–=´!`Ä3†VM¨“F`L%¥¬ÊYl€êoeæ—5t¹p` T©hZCd-…Ô\Ô=eXwY m£®C7U¶66›¯'wNíËbæÚ6•Ý+–æØ®[—Á¼bLk×w¥Æ‡—I³aH‰/Y5M¦hÐÞ¨š¦tëÆc „ŒêEÛûõ˜i–4ºµ&¬ÍÔF±BáåB¸Ô›:¢£’Ëbn@ 8ZÖÔ¬¬;µMSÇ+Cclâ$(ÐÆ$QâÖó<7Ö‡õ}‡˜†l'DÈŒ‚Ž?y²‡Ä¦–Úäò©0¹šjO#,î¢>o„‡…PÂ3åÕ3)ª“Yã¶Úï;uäËPÄ h`'ÃñÃ÷ÒSÇIúÃ)Ä°ìDЊ"±„HA¤¯qÞ}¯_"Àh~¨*D<%œ;þ^žï m=c©¢Æן ÍqC3Ñ a#$¨RAVŠ(F¥Wø"¡XÄ—åBª&Â1‹ÆPà‹#/¥ó(7]u|µ¸ÌBS™íO'6ÑÇ&@𛟶8Á¼oUQ E_…V4x¼·/ŠóK&ÖKy×S*YUÍs[ů¸«yeéÑ[%k#,ªŽšÅŠê»ª-zjö»(˜¢THS#$Ý„. °.U¢ÌL)%µ&­Išl™­Àm°#,4õ#$#/¢‰¨DdyÇE©Xýº!ÔÑï"ÖÖ 2Šö(¹j²)®\+ñHÊ¢—€>s0¡†"HÂe†`ØÉ–@2…‰9$²"ב *«È¹¸ì‘À4D l©ô?zaƒL-Úó®Å~/}ÈmXp[‘,'±}²@A’%Ç»«#Ǿ’¡ä#,í0‰”£è8!DW‚bUTŠUðÏŸ•Â\6¤FÊ;*„â4\T-°¸“YÇn9 .A.Xr,±á•sO®/H)QPÏè ,®‹øÄùñ‰¹Àjæ#Ô#$•Cg›Qu؈x¡hØ:Êï –•()j¤ (Ò–”©ªÆÔ3i¯y]±¦«4ÖSÔ®£h#0Pˆ"(’TBþ˜:'3 r<û=–ˆF«²dom¹¾æ©@¢‚åYȈ^ã(ÑÀ‘@:4B © ãܼú ”kx”`ÅJæͧ};­#ìaƒ$9ñÓªLM&M´P‚©‹‡ýo#,ËÌg8¨¼±†bCÖ°¡ é:q˜j5,ê’bcC&™[E µ¬pc#,°vº¨ ÄÓÃܘ‘”}†#$Œ(r¶ˆ7Û‚ Tж/¥-ÞÑðOCÕÛXD’I"BLÁçP'ÎQ Ò8ᛕ¸Ê>§OÔ¡ HT {Çî=’i_ŒŒŠ0”ÔÑ$PÝ0ÂÔZi´Cÿ¿`ˆlÐÙ$sÐÜ@£ïf{Σ¤«“g4Ä~Ë#/(jct3$ÇÇ´€éÒék’#$Cø1Jt³ff¸#’î:I†0(€«³ãW2Œâg!’T"‚ (@Û!).TΖ*B5MÈ >É®û绉œóÈpC'ØF-†èÁÑϪƒ®ÉÍ¿Òˆ€?Ë‹‘ÊÄ4ÏáýY˜I2r*­Éˆs‰s£/i‘ÃL³=…Xʤúá£'N‚}I樗ؚfߨÅCðûƒw¬ ¦uø̺@X)"¢›l ÂÔ”™,Ó1­Mm-I±­ÊkðÊè‚M*e¥Ÿ¥«rÚ™š¦È´P³+$­”U1,[eU+M¬Ó-f[e‰-bÒˆªmLÄÙªÍMSlVÛÀF–ƒ6¢ÌP4?;J?aûÚ>¦ÉÃmÃ\¶¤"f"à#ŠƒÒ)¿õ¥€5$n§5µFµ‹]M«\ÖìÞ#,¼Â£_ÇÚkÓjýÍ奧թ®±èwuoÌx#$(ר…JŒ‚5 ±=H$Èâ±û“‹ ûLP<¢¾­”‘q*‰2¥E±TwĤ,øÊ0}¸ÁAÔ“(¡ûºlH.{K¶Š^$(Ϙ‚ø#/z<ûøŒ8D (ŠTUöDá ÏZqCX~¶+‰ì°‚a!#$¢/H #/•¢þh·" {RÝ }*zО!{9^ű”xŽãá¿<³ØmÙsVƒ #$…Õ\’CB>³¿Ê¥§m©#,±¸¶^ÐŒ"¹é#/oæ=EÌfw¬ŒŒótqü¥Å\/ÁK 2ê¹­çÆö÷ú•MäNÐ(iâzI‹$^#/ôN±¢p#,§+U­kHEÊ%ÍÞl0wŠÁéÖ¡“¸ƒr 5›ƒwyc(;0Måá€Rxó£$ækAB#/PPµÄûv§ò¹º+Æ"µŒ!¨ŠÐÐÑ$p¬I—õ;j8J¢Š,ÜXš‹•;ÝçåØrløÅ(õ¡÷~%Ô>èceïÓ £KFÈü2ôS^º¯F…4}¦[Q°š{p‚w:_ñq†¸8tÖ^0]Àé®×_âätb¤a {þÝxqÏ·ó?RóiæÑ!!ï#$å5›ò6·Ô,ä¯LéúÈr`O›ëë@RMR#N#/²ƒ))e% h0@P0|~¯LuÚµ/̾Uç+ÑË+ÊŒ$Ú=L†&ð£û7­`Åû{ÓˆvÒÞ„™'·ûæ&ѬHU¦BÊ0G%²‚³ÕVi£L®mà ê¤pÕýÿ&XéËÏUÈ·Éljè@‚Y•Tñ0X#$I#$ l@&(@hdEiR´@âŠY,Š"m0À#/ÜþÒƒÃJdöÌÑ×»Ó:¾JŠñw6ÐøvÿÇ¡Ž¼¨Çׇ³M™;ÎGØ6èÄCw3N¯QˆqŠ© !‚”s«z) â=~'!¹eV[¤Z#$ôá‹#,ã¯Ý@jêêôìCM›ŽÜò&›Aë:ÃíÊ&²"úŸw¥ÓTËô*z¼%0<ˆ$äÁ@¦«×Uè¦ dKiyÛšåyçF‹Y#/´¥(d„Š0Š B*ŒL®ŒBHTˆƒ*‰F2Á >§¡ÐØQAl Gû(]›kRAÝÄAPGpa<I °û-³øúÖ"¨È##$¬K²"­™m ¡†a€Fµ"h}3ÖZýaM»½·®²±»¢ái— Ʊª4 õˆ#0©•2´ p™,¶ P“TÀUi–€‰‡(#,ie³5YB-°eSh²- èA’‚„KI{Ù6Ä&‘6pæQ5ªbÀ¯P#X¡²ed9q¶žB[ºaÑà›È”fÙ#,DˆHFÌ—#$ÂL&‘›øÛD#$é„‚J¯ è;â[‰E7rlŽ!0u%ƒɲوà##,%Ü#/3Ú¾¸ þ§;#/eâh’õd #/X@$Gä•1—%<9z;g`PlÂ}>šZ\å[½Þ¿P½’ é¨j#$J Xü ´U|XC)DɔĮŽÒNhë¡(Cªì-¯Æ­¿]µæVi,¨ÖJØ™hÙ-&­Rš×ãUêÉbT#$}öÙlX[$¤)#/`É"gjw$çÜ1ù0çW,%6tmSÒ6"¨«>ËY«!P÷͉Jpèqá¸ë3÷cW §Æ5ëŸAG[GÅP¾— yˆ`‡C¶ÏzO„ÝGžq#/¼óþõ¶õW›mœ*¿à¿%‘m—›Ý>“Ák}LÖãi„“dÙTA¿7”Ê#,ßñëǤ{×Øx­Úò}h`° ¢jš‚Ð7ªˆ ™#ÃÃ0뚆q|L=ž“$F*1‹mŒO§NAÌbÆ,QžŠÍæðì&Ù3‘°kŒÕ&˜†72^A#$ •·4ßµçC0[E2Ñ,Í)¨'´ø)|eÞßVØ·>fÒ öøÇc}íºþ‚7;QÀç¯rZ®Ã'H»ykh1&z>É{áOìôkëÇ‹DC߯µÙtf(5ô;¼}‡€¦­H‘à*·Œáp5ì=}¿eÃÛ„#/Nà ¨=âaÆ2®ØÀ‹r¯1)¸¹Ðþšlfoà|žÄÆ™×j]ÚN±œé­^y#‰Õe‡X¦´3oaáóbm>ª$ò2™íî/xs…F åÃíß/¦×}ÆÎOr—»S¢Píò6d†jØŽ¨S̓#/T¨OÒ—µ ¹Â‡#,¸ûŸ˜¼:æ>Káшð–àF1‡ÁÌ"î#$¦H Wv¡‚Š©†ILFBøä¹3TKEXT",!/ÞRÐ@à†0ÙìÒ÷èQ…¹íÑD#,¡[¼ØÍAú„…ÇýßÀ¿\ÉuAb ,Qà-¶‹‹„dÉ(ËQbH;¥(×VyÛ¹ÖîuÞªjÛ¤ˆÓĈˆŸ#/ÂààD!š#'‹v®#,¦_¹Òæz"N÷ê=¿zEë<×^…I&þõð1û›„$Õ¥µ­[›õ‚ûv§Ã$Š|vëãÇÙ›åys‘éS³Ê!¯Ú>m#,:4ÝÑ Ù†¬Ya!pÜ tRyjÑú(=¤¸ :àj•C…4tiÂ7qr<„–«b/ÀV‘àÛ,%§³°eûôl]™dÖlΗM²–@•AYÒû ©Ð­ëýµ§Ú#£+ŒFµ43„š†@èÂ4jÃaèä;ƒVu1"–BËB30Ã-˜WéÚ¡; €å1ÖïãmÄÙ‘F&ÌÄÆý¨mƒgV÷¼Ú.,¬P= Ä#,ç®n÷Wa³Pø#$ŒARy6#éoèõ!cìwœ}Z‚Þ:¥|9ú.``}j.ûz:棰|é8½m¿¬kéÊÿÃ]b0Va¨)S}¢#Õ®6—1ÒVøL#òkcë8:Ø×SÖQ™0~¸}³÷?÷þjB…,NuF»/µ™}3ÓÅt\n6…îb>ÿtEGt…ÎúLIbœ”UÖؘ^2#/ü#,eíh«Õ¶fa­}÷CÖ¡p…y#o&ƒ`#,B#/b|ôì\@8”Ãz‹â ¯†'xmo#/tCì|׉‹CiƒÖ°} 7´Pˆ“½£Ÿƒã’óÚ÷.ŒYÐìˆàÜfì@Þ@=ÞR¾°Èçn)ëÖk´€eª ¼<÷º°$’t"L"Œbà(ˆkeÝœ·Êüj#,rDL\&23uA¦—ëÅ0"ÐzB˜ßV#$ö„Ъö@æUƒžo4Úl^ÛCxþLFx„ܽ:B…ºM!p<Ë¡1ØJL#/3à(½ò©$r­êÆX1ç’âß౹ߜ]ôDI"ÀxºŒ¸;%?ËX,)º³é]†ý1A¸ÈäŠd’fá¾A1û²Úc”3…¡±ŸÑ[5hñ½JèXÈhãö>ìi é±,#rL‚ ÍRþz¾½Ž¬} AúÈ0Œ ¯TJóª„!‹Äå\C#Ê™šATÃN½—A9ÄJ‡µ\Úé÷Û¢ÕŠÔ[k¨Ú-¶Æ²cTšÑ¬–6±[WŠ¶æØÛ\EMl1…Èë42]ÿ;t½ÊçQ¤¹–¤¤b 4È#, Fd*ØVØÅñëØo:6ÝvýØ3€›H7,àw>¢Å7NÚö˜ŠbŠMJÏ=¸}‡ 6eöѯŽ¶uýS×í¸Aö©ˆ]5t<CQ„Ûdƒ"å›a¨Ñ4Æd0&3¿bò(‡ãØžã¨C9¬í~`E hy+å³ ò#,†¸!"!w v0aæ“Ò;ì‹ÕëÔ}AíÊçðûðæɇ_¨@Û&Ïðvl¢p`vã‹œÄà¶@;$™È8åß®Š_2CÐF©CÓCÙ[ŠŠ|C0Áýa#,¶Ú³ͪBfC:ˆáÈ¥¡5MR¶iE¿ßµë®˜% ƒgRHB¶oÌÞy(0ï ÿ£eõ:™™®…#/‰¶ X#,W9*ªJ Æ>2GǾ¯^Låw"ô×Z£z”“d™Iht@=Él…¦°@Õëb…1¸¾•Ž«„DŠèäHÙB(¥R#/ÐQ¬­f  ÈHáøóÕk×38é ²ª pÄ7†$d‚2ªA4Uj…@qÙŸ£êõ»êe>{}ýO뱎kÀÃÖ&‘„ŽBTÁ6PbÄd&©¡=©ì¯vq‚ùb!”¼&…CŸ¸÷Ù]•2K#¸°å}†¦6©ažÜ­òVÄǤõ£†Ž°Ìð(uUEB…mÊ=·e×àšŽûY ßý#,»5ÑaAUG<´™eÓeôŸÛm:W^£Ãåíåð ßX÷¡x¦ÍüŒ!DõѺýZË©ËÌñ›V‡ËS?…RÝz%²]PªŠÍ4£T#,u¬³FB™#/dª¡bÁ#$‡Þ›´›%'½Í<àcÚîBIàÔLlaAÂ*šŠŠIÁA¦HM)S35Š†‹Fºë¨Å#$èKóñâ#,ÐYQ›Ã¹ 1f…JÆ1¦“Œ†‡E­AÔ¡C C#Áš¶Ž=T¨Ä8:5£*`¨Â$HrEÓ,‚>pƒHhLímoÙ¸!dô&~©l5Ú¿wÏ…yvîÈI¬Z¬¦ºUÍóÍÌ‹6J´•s¤‘žn»I•!J-+¾<ždõ6ï^¼Q+1§­ÖìÐyuÔ½º×•I­DV„Ó›cYebÐË1ªQ^šóÆ®´Ù©”#$¨5+e+42˜ØÅ©$‹)´ØÉfÙ™&FÛ)izîÞ]W&ܹ·$nºå·4í×´¹¯7äM*Z†D¤œ1YrÆEb0c[0¥”ºTÒ^`\QB$@«ºc!Ð4´ÖÌ“¬ƒV­Fˆ Àn»'§7XDVÙF庬ÍKb‹LL6û*­c  o#ⶉ>\x4ž{*8É´ÚP nÜk†aŠ»`»à ²Ì1i¡K0K•(HV½mt¢Œ|;•š“ÃôxãÕ4¨«m¦ë¶jB[s¤Ë‘ìÚñE^̳#½¼×µ°Úá£! fÌ´ŒB‘¶›hÙÂ$©Vex¬ˆ¬(ÚLCFãÚXÉf6ZIYZôA ±¬%F³¢")"ÝT‚&0ÝÜF¿V\ã„F£ o C+vHÝ— ̃MN q›T7v:ãÊV¥„&&‚±9—óÕkckR"úšOå`i’l(A££ÃÍÄ£ÞÂ&ìÛÒ™#$Ï*M\2h}ÉêÕÜô@qž-©šSJ^PÙ<¨GÚ.ÃN'ÊIJG†¬ÜÚÚ0qÂÙÖ‘¥Ã#$Õ4‹†À5˜Å¶c{zª J¦Ï B– À¡‘#é5Îô$Ž#,Ú8Úöž¦e™þFŒ%9¸i‡ tÌÜɬð€ Ø|»MK_]b&È¢Þ×#,lÙ[íE»!6Ú±~.Žžl¶Ç\šàRa–&q[!]2ôb²ö³F5ô®4°xщ‚Z­%Sm•›âiu©¾8ÍBi)ÄãY!¡&s•Z„Z6ma¥CWªŽXv‚9jz1f†F [†â#ÏÝáòš‚ýÏ€U¡‚¨%H?ŽD€ÄâíL:-16Q'*Vác(3*­Ûß››ôJ>úyÃ#,!M %(Š ÑiD@„ÒÛ*Ò#,iR*#, H˜ƒØè0c¤(ŠBb¨cI‹\£H„$—›þÖÄG=çN£ÒQöj#,bÞº>ïÏK2Î):'uù©±Z\]@+UT9†>X±Ù2š?)(ÄHægÉo6ÍyÏOFñ>§~‡o‹øÎ6’·í}w<]SlŽˆ¶&¤OâúyCɽb¹êšÑŠFg©´ÛÃ×»©’–Fö÷t‹—¡ÊótÕà{4óz¹¬š¸Ùs«"–U™káä”ááç×CÓC¿m«c4¶ýfîň„’·33nN£fó¢ºç3naÙÆwhá¡A£±­Ö¾f¯#,¨°*°ƒ&cŽv hîÆU6–dI#/ê»–åçC‚÷®iðyng~þóCoÏQtPh£]¶°a&òù¾ƒ,h#/?˜rtDÉÄÜ.Qå7Žö£÷õgg^i¹åÈ»tÚƒSKM³jºæ­úì䇜ôMÇi§#$c®”BŽ†ÿ_¯†hžî&w†c™N™ûûew¿‡åáo!³b#.÷jkÖÍRØ™×#,CŠS)ÕüB0ù|¿;Ÿ6\|Ðà>`io ‘Y!#$ :¼FE˜…°´%Ôl–#$úàHš6Æ‘@²ŽØ˜ˆY&TÔªQÈÙ¤4;U\#,ªÀ»6·#,­Ój’ÕÞ:,U‹^u˦®ÖÜÛ»s!Ë«ÆÔSÃ,–-"Ò1R¥\㺮îÕ‹Rm–¦¾*«Æ·’¶“t«vÝyæñŠÅmâÚ*½óKhIBÍ#,/É‹hXŽiBšª•Vê»Y×]ÊÂôâªZ(…”¢…DŒ!B4ÅV k*Ï9"0…ÕÀ IÒ2äMˆP¢V¢£L!PÌ…Œ`¢H†ˆ@¸]ø¼·Ó(k H%I(†X@QQj”¦©ùŽª)²‹X¬ÄÍ4¨¶*Š™ŠE¨¶6³+Ó5I²Y”LɉTÑDmLɲlklÕçjº3²”#/"*@æ}¾’ã¡ }ÿ„bù궼õ“j¡*DI,¿ž»ý³íð¿o“Íà·«ú=w.g6ÎÒÁêMÍÑÏ+«»äÈ(r/óQÔï$ ,V·âjiµ¤¦Vö9¾êêhÕGìÍo±ZÜ-«Å®Ÿ·ÕÔ3ÍÝDm§wg]k»IK[sm£ImÍr泫´¥kJÖW®ÝšÍE )H´Ñò³þ¹ ‡fàFè£ÂHûá@Ì4æ&‰ ˆ$AT C™±p&òqÌ–ª€¤!ØdƒFæ¨XCa×Ëx[D¡(6Îa Áy$„50^5+´¹†)ÂKÙøÔû®Ô÷Ž§Ëƒ^‰¯Â,ñÀ±ªLaƒ>5ÙE0.`*ëD†TE„úf›#$‡ÞxÀÙ°ú$OùëÄ͸Á½ªfc1¹ó²ÁÆÆ1•ÜÉ4Ô&1€¦ ÚšnŽ 4Ã2Gœ;“o£´Êq)mwŒ„¤yú·˜óïÚ´! 6ÚxLl)¢ ˜¬6|U¿¬¼9Ž0NëP ÖÈs'ÞWIv6_7{Æñ£ÂhSK͆dÄ—‘<Èãg|–Ô¡àø¡E]Ûì®xÎMð²ÛhítKEHæ¦X^¸Áƒ† ¥“#,1.ïg¹àš,Ÿ’ñ¢HÆ ‹Ö;¢ä¹Ã…øèVî™×•Àì@Q6©³8Ùlý8Ú~ßòÖ<0TLU‹}&e”ꕵR±CÖI°ú›QG’1 ¯¬3 ‘7Á>ˆˆÂ+ ¥hÕ%·Ê—ÞV®š“Mòq½#/¸ÆEFÄÊ#/6!/($Xˆ‹$)#$……ËÝyÈ#,qòÅ\¬ÿw†ì;¹QqŸM H#/ D _¦>â: ÷&/êq‰!@¡$Du×iíÅ‹[›UÓjñ¯%ªN®RX3#(a(I”Æ•"“"ʪ™ †¦b`'âÀH¹·’+lÉ1“mjæšÅñöÉUçu\Dö]â®Ò"6—5ååE=ÉS„«IÈDNµ›¸V<Ócµ²3(i˜6ÐKhÛ5jRƒB­´ Õ…ZdHTlm L(Q"$ªˆP¨P¬V1`4¼TrÀLÄ+²¬?t#&’`RàYP3.l°Nðù[+¸Å$SLb ‚ƒRYR@3Éý½þ|ï9P½u¸ÆÇëÙôFX}çá†{‘Õ8|Ô>'pív¹×:íå#'\IË—“î3&ðI£Ç< j6lÏÛ»-¹ s;9`S‰@$×ÛxLD«zµ~½^­k{‘Ú`xg—Ö|@æC鶌­F'áŸ÷~ö¥èa!ºÄš¦Íõˆq8PýŸÜßsÁkùZ#,ô„Œdù,dâžö?FM8ÍCõ¸#$Í¡qΆp|å¡Q< ‹CàêuHÐ]#,Ðô2îË—Œ€ TY¶ûÙÑô#/¡lxÅWŸMgKãf@_(¦™#,Á@7´"¢IheŠ'™­šh€A6õ#,‰œÏ+„½1ñQ‡ÍªÁ™cBbÕ[Ã’ƒk8( DRª%+H£Ûh#$)`®;Y@É"☮-ƒÁã÷ª%âýÁuAÁȯFœgdï‡_»¨$±-ñ¬Žî'¶©õ>ê›&áò‡6»#m›Õ£#$3âU:sˆÎNô©êEýOè>¹ÀÞlMõÊ »sUt¢Uݬ·ES#æ”1« gü—úJ¨µq;S ¸#,Ÿ ŽáC\¼„¦€ª¤¤VHF)€”ÆO`Y°ŽãñÖ¾¨É±´¯^ùçžiÞwYrÕÃJ:îñy#,‰Nneæãi²ÈšI ²¥¨ñ¶í6É¢Å%&Ɔƒ snW6ÜÝÇtÞo.Üu×lÇ:+»·H®^-ãɶ9M–òy-Õ˹¬Ë»ËTÛQ#ÎÛk›–ºj²[F¥,m:ܦ̲lšÏ;º7NZîÌé®H¥NíÐr®²çY¨´hå JB+P$Fˆ+GùlØEv·K"ëOTÃpŽ¸:Ñ"#/õìôî°:ÏLÄ<`8#$v£ý}¡Ý Áƒ¨B‚R ŒD°¶ »þÀOE7'<”Ãß©´m#/nY)#,PQÖ#/Âf›´•¬„ˆÒÕ tn–±Ÿ¢l>¤#,`ÿ–¾è< ÂH œU:¶Á¢¢²¨#$€EQ‰‰Pª*œBŸž)¯u±W×f•×«NÙ«rÀYƒdj TNp,êbF"´0ŒÌ¹ÑwÏ\#,¡’y'7 $d=EOêDÚñç§í[Ýa3F×T5e–‘&¢Ú—IÆ,4øJ¾¦\C‘Æ}C²^šõµ.v¹’µ5Æ1âì¡,™&8(BIa]f<™·d„T®„wø±ÐÈmšZ*ÐÎNýœw|»ÉÁÊ5P«/*­¶Â½Úa_?°îq^.úZ³ÁšáO˜Dïh9àTø³뎴n¯„¨ƒ²~UAœuœ·‰´Gø",ˆ€Iꡦ#/«\©áj"ÐD뙬â\Λ[÷@-ö#/o g üÞ¿ÖõÉÇ~^P?ÕÏõAÐóž0ýÀ‚#Ši LѧéÖ¿ŠÖÙ>æüI$#$t> *hÆêßÊBxÏ–=%¬X¿¸¯ÕöV)Ñu©A_´d EQ²{xKÜáûrY…op–V]½Lw0Á¯‹(hgEÏËW£ p ´†‰PEG¶Å´2ÝÖŸèg4ÆÞôÄ£Rø®¦’ÓF»Å¶íÈ„ê8i’nDóÈîhXª‡&“£»6.+„Í‘Ï‹ Ù#4 üøÒON'è8"#,$´xĈ†AdÃ6ŒH–±ñÈǽ;ÐCi»kb‰Û‡(‡æû–Þ¬‹îbÛ²JC”DÌíÛ°Y"ÜP©¤œ©æ 4pQÌ®®^'b¶Æ=ŒoiËs EQƒì’a}ݑªžvsFÙ“eÕ“¾·Lc?tíÄ[šþkö4ipË,Ú¶á+hBÞãœcCÔ¿Ñ4}ÞLé9tE5&›å1œêë+Ï+Ós>Y !#—V‘ãÆ1’@òx€`؃z†'¥„Z3xŒm-1è“I£4»dîÈdY9¤™ñ—Ï&·=»!ÒFv›â"GD!A&ÑœãQl ™­¢æ öžZv³¥<Òöþg­'›#$·’¾'R¸– yG±&èÞÙƒêìÖ‚QŸ‹'nE«ÛËŒûm°S”#,ÀÓ5ÓxßÇY]HxÝë0›´¼²‹÷ý*&¯ âÁ¥¥Õ˜Z›Ä†í¾œ†cAÑ)N)ˆAoëD1œ!³ÍB)ˆ¨¦ïûìƒY#¼äõ¿µ]2¹"8n°­ˆbF#,¡âT©%J4‰tÕM#‘Æ$Xˆ’ÙˆÞHèÁ\ºYAUé{Ä}4wÀ½¤ÁU±Ò¹t#$³2ªƒˆwtêé³<€•?„³Ê]H\³Ì®¼›â_€×qÁ{øÓ$5À=|Ä@hì1+Ö!"0/†óI†½ ™ „h|ƒ¶Ìðà£{l‘X1õÎ¥FÑãÙS¸£qÑKP*Hˆd:ÎE¼ùvâ&Á3ƒdÈÕµdáwsDB„¡ÿ‚•R³ëaàêÁYš¡ÒÍ|+Q•UjUUg§ËÖ±3A¡÷ %$úÛbá$#/V !,HŒ’"SšðÉq’©SV­/½­]âÊýž‚Õ=·!{ñ4ݘT¶Ö•ô›•ãÕgEnñ Ô"ñvð©a0ëÈp˜óÇ¡ªNÚMwG"Û]#$É;UJ‹Ú5ÇO+Ř+a"Sñ·³Tg!€yÄ%@ðAKÚ”‘:Ë´#,X¦"›.[ó×ë™ÖÆGÍÜ´Ï\Õd¸@°ò#—ôS⛄ÒÝÓ>Àüb|)J6P'srFçË›6Ò±­TeBŒ'KóÛ¼tN*¨LÉÀîÏmÊ tþ#/¬ÉŒÈëïØÖ‘“¾*”-5<¡Xä1Šèô>­ æŠUwžÎ~Þ¸áë׈*hú@6å†ÁRŠMî#,(Bf Ý—8ð¾€kíá`ès9˜úÿŸßøæ„×Sç(n#,ïÄ.Á‰‘~’+x#$I ¡Ü§zCâP_᤭ûöÙo[ðËZ´Z&¶4Û(ví/WAÖ©ïÝǤzë¸ûkÌóLFdm "›Ñ6u›ØÇ{ÇY¼>g¹;%Äé<ͬ4 o˜–é‘mÀ‚9ž“§pâŽïŽàêØ€Ð,{çÐ퇋„û+læx€f#,qeÝͱ&C“&ŒYôMDW‘@¤‰¹#,±<•&=T¨s^TI $ƒž{÷¸räo8BeÙÅ_*<¶T^Tzìšzyq· ZQòâvNGk/¬Y©Ãa>ðQL #$°@€1#/F#wð4†u»ÂÛ ìÜ㨓QÔ :~·¸ÑÜ#/^¤”´!` c„€âW8µ¯³ŸõŸ×ífVREë§î)¤‘´ÚÊÛLíR‰È}Û5ø*€4ƒU 9È@,¡ ðti¼÷P˜.¨‡xÄãüG%lo#/tâæ’ü£Ý3?j†™ÚKTçkéÔúÜf†5ï"Š ýÕÎlàd]P6мÒY-è´Ü/¯‚þw‹®·L­3/H_\| 0ƒ1µý·å>ÞU«È‡ûýÕÐÚµ•ìZA+š_ûz^¹ ¹;}Û¥ÎtkmEVVw—#/P5ö2ìCuÁ”±`î+¸qŒe]°§¿ ^ŒBk‚#/AøÛþ/–Ê؆ƒ–hÛ»0«ÇÄ÷ÄþŒ¼oíó†BBFÁþ×#/¬U1ȹI#™øåÖ%1¼W†ãy\á.\i¡ ƒ§Në<Ú<î¾ÿ’Īì[þhŽÅ $œù¯-é·Ë¹gÉtÉÁªÓ½wh›HD"$ʆ„8cÝ€xî£HçB‰ÖÔ­±#, lé‡ë¨HÆ6~¼º$g#,Ù}ï•ö"£\D—´÷o~3HMØm®iäæ9\«º]®ÕI£X‹m–Ífš¥›D´•ª`‘@‹:öë°»^5¢I mC’ä²M=—6ûüOÉ#tQ=”CÖ¥Z#$°EWêý¿£zõ'êý¯26ŒÊ3dˆÑ˜ 4PM6‰DÔE&!&4J1¥*FM‰¡HI³dØ¢,b¤?ŠN\_vxÀ!ø²lÉà*΂>äÍ÷&ÛÛ}n¼ÏÓ¤“fݳ(71Œ6#,‡)°á¦5œ,k7ŽyPÒÊ€ø&ø˜·éW1Ëë?1ŽoB˜G^#,4ò`¥·mŸ@™@¨…{jE#R«5sQƒí«!êï1½Q†LˆBV̆¡‰¶ïœLÆô¸_£#,€¶ºi5U9|ÝQIé¹>Ðc°™&AïÔ8îbjMw¤êªdÓÒ„@Ç"é£2÷^ƱÇ`ûO¿×¬3tg-Ç#Kó¯ã c_{Î!§¬5H6›|)­¬xÕ$‹ù¡&_ìÿ[;çQöÎ2¤Ó|Ú#$Œ'íD E¬¶%S)JÛM8ÒŽ#$`šƒ‘RZŒbëd-Å…7QUË;®JnVÝ®ésuv¨1¹¢Ê6ÒM FÇ#,V1¬râ!…m˜Ø›hÆ@ì’1 Aš€H/+lJT!v…%¶Le…2ÂÅ›Õ+Q·×WŠ²H‚H ˆB#2¯p*åÒåÖå[mÚõËŒöÃ[s¡µàÌ e¦"û]@¦-“f@©öp É¢.£x*U,‰øµS+.¤&‹™¦ˆ¿ÍL+ö?izœ,›G.šÀè†c*d¨äC<§'¢5R_ÈuÆ׆ôR¸£ £©‚À«WE nT:)ÅšÌPy²¬`½-ppl¨¶n8$F„ÚEh$#yW!fjƒ)WMSEEm•%#ÈEZ¥·’DH”e=TlFah’iB0‡ô’šhU´T#,¦Ç‰¨’ÆYm©¦ÔÛ‰¦c"Í)¦65‰¸IƒMX•#,‰ènJEª‰×*­:R\£³Û+­µ€ PÛ«‹Bu…®©nA#/…p¬¶ŒiÖÐÙZl¥#,•-æ”aª˜ðo#/¬TÔ#,#,ƒ#$¡Í\Ľ‚S¥0éî%H%*Åp]ƒÔUÍÕ\’íj @†•  @ô®e­1xf“dǘE2VÕÙ#,œ‚¢0ÁÅÇ7âC±s”¥`«NÈÕh2È’Ga%•cQ¨œúfÍ=,$‚íðå]¾:5<öÚÌYädÆ#,®¬VÄŸXZà:âˆÑ#,5M2:Y‹"‘ƒQdñ¸3Lp„³xc$‹¼šÔ”ƒ…*8Û˜–0O#/4áLƒJ¼M/)ÂTqZáÕF`ß)Á‹Z´œjŒ#, ˆiQn…Í@dWc ÔB„"h2Vj’RN‘1­C1‰¢J‰œ÷~¤ ^ú.6Sƒ+ꚦ£S™XHX‚Á@Þ¨Î*Ҕ˕δ"L+"†##,3›„‚¬PÂ@‰¦Œ± ­ ’#$Ë#/Ъi9AŠ 4opAßU@lÓÅÁlUò·†!·Ìšpx#‘!‚lU4M#/DM¡¥ŽÇ,Þ)FÛÓH{Ú1¶jÂPsvº#¥¹SxÒj¸±š~ªeé6S6lC9*2š)†®=Ì¢²=<­Á­Ò Qñ'¢F¶Ðjð·Ï™†ÕåF&ÉwÈEö:Ó{‰aB¾˜>˜ˆ–”ãã£AÐèÖ5U!Çš%µ^]²3cX E«-‚6™4Æx5H1Ä#,‹»§]Ä`Ñ°EQ$D’ÑØšgS#/hˆ‚F’ÐlPD—0Á#/6‚‰ TPE& ¤lLP‹{IfäE$C¦µ4H¡PŸ¯˜võŠ%R”Å…[TÒ²ª¥£þ+«ºcTdµÞºº[øÝq=\ŽéÜ•Žù_ |ÕúÛIA¶¢Ûb€„X¤bÁ„au+U,¢xõJ໼Œ1ÄiÐë¿ôm¿0 b *(!"À÷e#$ôÈŽÌ]ÛŽû/U}ØR˜iDó¢_T•YØ>2EB@!‰ŒT£4Ú‘Båµg{)"{*RTCÝ^AÄv̱÷Ø×#,* p2²}ó¤JûØsËÌQ‚\¡¦a•–H%7V•Cדøí½zî,]ݱØÖêêé–‘0mÉè4 g¥HQ¡Š¨6LmÖ 1Ì¥ÆÁî âE1‘¨Å Ò#/}Ò,¡¾(i½40åjçADGp•½u#/.<_íú–Â#aa°“6ÔØÄ»;Éc\%ÞœåöÙ®¼[ÂÜì„‹:)0|^{-k“„‹ •›Í;óJôˆ%lJ«ëþXŠŠ!@tœ§á¯%C°Ë‚ðPÃTP‡XÆî.d•–ó¹pš&£´ü:¶=¹Ñ{ïJÉÐð†*È”AÖ¾ïÆ)í<ãü}šºÀþSâS e«ªïð#ó:±í#,û¨þƒéu°€yì«ìáë8áñ°˜ÚgKÞ?˜û ¿Nº[}úG:HX¼0";¼—ë›ÌƒýÀ`Ó¤Õ…&¤ƒQT*®ï©:ÄÅË7ÜuÞÓ`wÈbŠn½CŒ¢qØ–Ö Ú«U€<çS¥Šš»Š¨TE6±vÖü§+;J ¯âXO\µS†·Ác $èȇ`ò;bY*AØ‚eb‚ Š©ö²Dˆi-;)J¥÷ULíè—-E_ScYª¬±#$ÒgA†þìKÓ!«š¢Ã]µóµžFø7:Däu€âkŒé¤ØÐXE„P!ÈHh¯óSA†ê˜w‚"°ƒ+#$ƒ$J6 šý”+"×´æÖKh·²ÖìKrîíjåb¨Ö4ssk¦ÖÝ5d5¹´›kšÉ®\¶×6w{5ȱ¶M¨1F¨®^,Ê2[†CÜË.ì8–yXCàÀÒ+ï ±ˆÊ25qÏUðfBVAéMž°ò1BöWiÆTÔ‘¶ Ñ¦ô­ÿ ‰.ÒFÞÝ»ª¸ýù>&”ÕPê‹ÅAöJ?@‹—܈~²(P2M@{çø©%¡LÌ"bí È&·¾]ƈƢhb$m% $””B)(ª¡;{‹…xÐ)iuHŒbÞƒ`15"† #$D@DÚ۪Э®“`´­}ÿžÛÑ‹·*˜‰v÷x•lH(¯( ,£I¬‘¢ª¤«cWóoÃ}*‚ Å@éB?ö#$Ò#$š¿‡—HeõÕŒš4 ì4¤l"ãŽOEíiAÕ½CœBRð#$s#$íŘýÇj¶ Ĉ)ÝælJźŽXõTʇ‘ëÐ2`°9@FDLbSâ¨Uµ:ÊZ™›$’”0lbÒÉhÒlY¡µ%‹)II)“hÐ¥[DZ¢­ŠÚŠÚ–•¦jšL©XÕ¢ØÚMlÖóñ™ð­Öä‚ cnµ™¶A¡¸ñ¤FÊäHŸmà  ÆÓl#ÊH8àÆã88cƒxÀ‰ÜƒIP#v#L G•A#/Ò€É"Q¬aŒt„˜“p¨¬M¡²1Œˆ° "c$µ„ˆ(Uƒ£¦L4"%®º²¦éµn­¦Õr­ªE@ ‹]FB‹â*#/@¡Œ³åü9X.ª˜vÒ–„Z (‘h‰7wNìÅõ?"»^–êõÝ›kÂD"¬HAlaVŠ´:ÀßtÙ\Eî±·(D#>‹?˜sì’'eO>¾ßLû+KžZ(¥QJöô RF@‡´.TøÈH‚#/L@p*§¨(6è ž0¢Þ*bcÕ}UPÄûí—¾üQ¥¹c ££Ü¢X†h·áÆD)§åãßYwYcíi fÍ4ó¥!¡#$úH‡N#,ÔÞˆw*ra HKTJ"pïåÛ¥u¼²êT¦e õ.õZ¹¨«bÑUjsmÂõ[´± åï™…áúõ¢nŸÚ¨Töb©4{Ü6̤B’³öiµg0]œ!׳>WZ ƒ@Cͺ¾Ðñä‹äC‹¤¨’.&Žo|zY÷F"Ë`ç`΃՚‚RúÕ ÿ‹óÕ¢4•/!Ô(Kš³ET¦ù5dù5\"ëC#Á­{`êå‰!U²9»ŽÒñÌ4#/d{í.¸Ÿ+';•<ïì·6ÇD!ðJÃíC–·N”'cGçdqáÙøÁ[ƒr‡56ãSŒIótþÝ,êõêD'Þ€ÀX> *5»‘å—Åã°ÏúÑžÏdW£\n†èª%·fzET¼R!#$êŸÙø¦”[#$]œúqåc6:b›tu«0bªY·©|uƶ݀ ´á¼»³Fz빕Z•Ì'É\pþtÀÌþS>88ÄØ-,¦bIN7.ÚSÛOl:Ûgæ=þãy®®wÛ4·Dá㊠†d)âULµH÷ªÚúIv„æ¦zú½ËZá¸j“üêMÁ.™~2 ³Ï#,¾îâè€õL>õf0²iøÚ»ˆ‚DëìÖ–ÉÁŠY!b…SÊÔT¨l ŽpÎ,—5Ò›ð=xÿ½~<á„æÎY™ÒŒ=NÚ›òe7éÄÆË4{„.eÖ¤}¯ikÏ}Ê×ù;ØZkpíï‚]…A¸ØwíÑAy.N¾¥6»mf%®®&’0Æ.3KÇ4ajÎe¸×l¤ŒR%B¢˜!Äg ÷7ÑY kO)*^ó€ÞG¿W{¼K2L¡Î¢+¥"ææåöA–ÏXà¹GqÌ|+¯N™Æî’I¨™|ø¦kŠë™)Ž„žè}¬à#,d*ƒC(!˜­—ÏËŒðxYâ\Û[NDÊn+š•ÇÙ¾Úxm±lÖ2a$3¶ü@ÕÇ#,xzk}"r?ÿnÁ)‘ž!šÍÑJ‡C¶éª žžI$;º/€O™æw*«6ó BÄ÷ÞÔXt±ÃFú„˜%Äï›S1LN†Ëv6ÜÞ†š,ÄÙšÓÂôåÝç¼öÃŽ•#huyUEÖô÷¶3Êu•Ç=˜©ašâô‡~ja67{—}b¢;¯Deð™iÆÕù<¥~øóäìê¾È:]zÌc¼_¯¶=½Mû†þ)„K8Àì;±“ÑñÆåvXÂq²XÆÝiÅŒá1ЙA0Ì™\KO±3µ½fÂðÁCj0½§#iäGQÌ1“l¦:ÞÂÊnvyS»åÉ©¡‘Ë”(”4·´¾+] o™’®¤¸wªd<ã´c ÞŽ>yTlÏŽ1'À²™‚q^Œº¹í¨)¨@m¢‚ì…Bøˆ–¨°ÅeçlJH:aµÝ1œ9"wÄx]É1¼yÊf;¯KB+Ä$gBÅÀ×JëÖº‰9¥#/¨ÜÑ)®þ Ò' ãÏç¥ÚK°Ø¡­p9`s&0¥û=š„"¬0ÔA”°d8ã·)κÆéáÎ׬.7(fóG ‰%—P@7VŠß­rªv ch9#,ÉÖº.í°†(ÐÈ#ÑLCö*ñ#$€@=œ*€€‰ƒX*€LhÀa-HñÜo†ˆäb徺öuãŽYؤvfr(Z–nUÁ·blß*sÍ+¨Ô¦b‡,#$l3H#/"Ï{™i†í¹¦6D%fÌî\Ⱥ«xšî`äð†©Â~V¾hÈ&¨<¢…C:¢ëof§°è•ÍÞN;-XBˆÓnÕa¨Ò3“* ã x}J°ý3ÉÂ#âa3a_*TÎ+9÷çÚ‘å¶]'`ã\éµÎ£it°ü¡ÛÄúÏòghæz¢Çc¢¥¥'¹åÁ¿X梄QU6”ETÔÓ‘¿Šj,Tý¶çeñÙl¶žÐ|dpCÚ×^•µ#,¾ääãÃe~ï.B`§:,å/*'”3´}«çž²¡æ°™˜–†(Ä¿¸ÙÈ…>õÈùç¿Ñp²9–žfª7 ­Zæ0ÙºÞÝCë¡ß’šÖ‹NÚ21D‘ª!ƒŸÊ[Ø´þiU‹WÕGb†gø–%õØ#u¥Y­D´Èæø}åÌ[˜âtÍq[b0ÊV5õv²f¢ Dv:e£;F#/Ç—MÊìÜXuöé鉾Øb¸Û~«#2.Êü9ä‰mÌ`ëØ5„/$uÖ¸Rûd›N—-¿©Ž(êku ý¸«Ç¸ŽŽyßFèYóÝü­Îòæîü_hÕL0xNq]åÒÞ3—Ͷ •#/îñ©4vK#/z©ópÄÜB^$wÛ¾ ¼§î<’¶­P®2yQ†g¼õp`rÐ¥‰K©¥«Ó@¡ö™ÓIè5/Œ5D4·ŒÅ› ÑgQÏ%5\‹${qyÎÖ@”ç‡ñvÂÚjªÖÁïh°ìYÑQnèôz2wo.†O›œ‘Û Ì—z¡ÓG è¸Ba#/7Vœm—艬5<µ¨šÐãXC±{Hç¼¹a! ®YµËÇîã`P—&c½ÁìuÙXg2ŽNÆ·^ò……—Œá4E!N岩«¨T45à£È¶žÎ&t‡L‹=ô«I°nyr%!)¢ðBÊnLZÜPjb\ S­Šë#$åPÍ}·XñËe©ÐRßåæ*Æ1ƒK+udˆ×/¨ÒÁí¸i¶í®o Ü#,hÇHiþ£f-+°£W ¾SJ§ÃÝ:kN4bJ³ÄðÖ:¸`@¥,׆cÉ –(2ƒtHqbePDiòãOR;Æ]ÓxÖa%‚dHÌ¡LZLÝZcÜsd0¶nlcoMÝÛ¼ë¼÷ó^"ÌÉ®°€J墣ܧñyŒèœ8øÜ<#mŽv4Þ¸í5+‘Z3x#¢Ù7T€±`,ip QáˆlÇnåÁŠf¥n0±7#$£Œm×±—¦¥4ÊÑ׎v²ÍîFjh£MÔU¬zmkZ¦A¸Lk.<“­†µcÔès‹œÕ²·Ã&ÛØÅ ®* Œ#/kU išV,p^,u— Mµ¬Ù¶Ød™ÒZü·Æµ9ç'»0ZQŒmÖ­8lT†¨(Du¤÷òžÞWjn—MÖNrdצìx«¬bÕÈd@`ÑdmÖBæ¤KÀmeS\Êùf•“%+XIw­Ü&]J&0gHnÀot‚Çßh­siH“°N'a§#,tÔqë³ã†•DÕ)l£{*5FGáxHéòç1cSˆ‚ò£œµ.¨CZF†™ÁÑ •Ž5„[Fᔤ(U†A£q)¡ÃH`Ú`ÚbjWZ6óqmäÉe•ÛÓ†ml&åÓãA €ÊÑ#,‘R¢µÕâcÄU­’®PÖˆÑa†Qª»vÝÐTcò|f¨c¦ƒ©¨-9þ£ÀÑxpJÖ^ûË{B¡¤aMÆ\zâ•XÑ\‘ä—…Fø•ÞŽ‘0&–i±³¤ÃTÃzÓ‘2Šö»íŠl•5R9yn°¥#/ÓjºÀî0XëF3BÖ‰ÈÌg&)èÑ39¶¨‰›—éÞXÌKGGoËÅÆ&˜Ì-8^UU¬DÑ+oõv§üMè£Ú#/Ô}+ÌÇÑ”Qôb,bQîE£ nÊ`¢ç¼#,4õb7°äpÇ2š4ƒææ‰#/pôÛÅ…³)L8…Ù 4ÃV3;¦Ú4\Õ…jàË!ìižá#!Ï©,ÙÐ{¦¡]L‰Ž#o\01'BÌðCV#/æebkw9*hÛ2B#Ñ*Œ­N4¡®2 Û#;ì‚›ÀÈÔjA¾ÚÌCYg@½:Áx0ÄäYr!¥vªŠe¦ãäÃ37¶-íã"=OtÓáôr~MT¦Dˆ‚‘)GieÝCc'{sÅ4çÈ4ømþÐ…|*P1DŒÝ?%«õl¤×½®ÛµÊâ¿*çõ¡C¸PìÝ<-Q‚}¦NhSÆIUc65«p#,!Š”Æ[v~ó‰A„Šªˆ=þ•}ì)êi¯Éún¬¬Yt錦«¸Iï:°÷ŠtŸJ¨†Ÿohm“¶‚2H;+ ÒÔ ä#,O¯³ÀždïO#,ÉF@ghóöyzÕg§‹ç™œ&·Úrkm-0x·ÛûÚ«Ë%bƒeª•ÁåÊf{¸Ï~û¾î¯G«¹né;»“ˆV†‘ª•UNyg›lòõ®þS³€ò)G˜¶´0ÕBl*‹I-ÒŠ!b¥J%h–(!öÜì:nî†&£® Ô=7Ï#/BA¨ö„6¼Áh@¼‘¨ÈŽì¶’’®Õ2–­/.¹«¡DmÅ#$QTŠûÓ#$6þºÉ<yÓ²»kÛÛW¿¼’$ƒ!# ”Õ#,2ÖØlcdƒ1ŒLcH‰RPµL«ÒضKImX¤£lIY4aE6Tm†m#/i©Rl’šQ *#CZ#Q)Ñ’Í)²)TÑ…¤˜m†0‰JLhFI $#$Úoê7gà_Îd<ò=‡#™¢‹ì‰F<¬Þ“µœ¶Ÿ|Ì],d»h+õÍ?$$fï#,ä7ÓÓßm/ª¸›=W)'£€ HZÁÅÀõÅ#$*ÀÚ†`À¼HgQT6Ú©z›ì†Œ]ƒ³8ç#,0ÒMM«så©÷ÞšìÜþD»ð;EB@Y„Õ³hÞm+¬ç³© ÛE1Œ$%˜žŽ²òI!uF«[È÷ùøäˆ>ý:¯?F!Š¦UJPåmN‘üù»zOÇs}M#/5wÆ÷ eþÀ> äÈ#/#$(‰$Fhˆ¬ ˆÕ%¬Qõ5ZæÓcR…&£F+b3õªB£#$`„,P*U#ëK d]ø†Hza“,)H0©C$(ü}¹ÌÜmF‡õÌ+ßÀ¸6 ú B¢;#/-CLÄa¹óË£Uø8ºènWUx#ÆÓˆc¥¡Õé=v#,"tñ> ­MuòN)Æ×%yꢹ`c6=¤„ˆEï9ê,:±Û¼ÖãØ»/ÁyÉÄ0†Î„"¹|$0ez¢¨‰T*r=†½Iþ™›ó0l8î°)¸ÁбÚë w—Ô¡¤ÍžA‘éè#/pÃâÍúU°ÜªxYôw—î#$ÇÈŸ¶Äøæ·ÑlgæDH%óŠºKLì¥+Ö"VG¡NhƒŸÓÎ8Ç_R3–BÁ¹‘mݽšÉb2FÈ[œ¥BHÙ#/ßyv+ô‹k¸XgÅ›”§vê"ªÞ~˜œ¬çLðœ424ÌÀà(B– #"©#,wKÞ–#/¨ùÕX– ˆ_õbER¡ó.Ì‚òe·"ÝꋳRU#,L¡“D‰²I#e#¬eâ؉¤8%–qÌs»#,B3eæh@ e /HaÀ\â–v£4‹ZÌ#,(¯X•3W½5Šk˜yt<âkØœ5Ûy'׫ÅÌ›‰¤OIÒjV¸é:±h„5eá .W8zÌíTS€ìˆ‚]9çRÌ•*8²Òëáεl.瀵µæ#/Íø§•»;Ñvw*­ë®4ŽE]Mtš@šŠÄP£Q»1#l™°rS¶æ9àtԷ˦•..g[8##$ã¬;˜9õ :Þ¡ºq1–#,ô"#,É+ˆ‚Xw#ðtK†£G ð ¼Ì–³¢p&H ‡X˜”÷‡\³2)ÏKLSWËj>boÚ3‡’dà–a[&½œ&Ú7›ð, –VJMjfÁ‰LX|rÜX[[ï˜#5…0CL+ ó×7íßK²¢’#/ɽÛ£%š‰’QXÊêç³Y4žø¢§®8TŸ(â«$3@ä½Ì·gnªÕ ³ ŠP—JPÍ KqĆ™gl•ª¹ƒxgAH#/LÄ#,D4(4(Ñz»ïƒ@ÕÛ‡ˆ¨s° rÓmSM–\ éˆko•LW0d‡“êùãQ¦;r²9Mgd×#$ùa5)©“2:rg¢'—”+våÀu˜h(?híÓµå™Þ¥Š–vA=3±8LÉS.Ž<˜9ÞÝ“M7ß%†8Ž9Ê¡Ø-t†„ŠÑ‹Î®¯Ñ®*ß‚’w£|9S 2 ŽT¦æãºÄsBAƒ 9#gé:0*7¡®‰#3ôI4É"ƒmIEHy!ŒU4"ð £#,$\U(j˜fÁàž”ºÄ8:ðšÑ”`#/ÎÓ%ïÔX€ëåÙp,©ˆ6aÔXd–2B"$ÜЗsQvSBkÞeÉ€440|ȹ)‹¨Ä9fŠDV1#,„-ŠSWHhM%™6Y* ân°³3,UD –Ï7Æu5z­2Ò‹]muqvÙ‹ŽÐ©•\tC;$—j2 *#,ˆ¢}Ø,Þ@²"ÆÀéF†6,™)šodADàbPßnê²2B5ai[*› lN!@0N#$\a¡ÔÒ;¨HÂ4WE‚šI‚j`6%Ò"&#¡œQ´3#$€¦ˆ»àSƒmµáɦLb(ä3t!ʼnE@78„…EÕ3*L"[!agE"‘b ‰>ÂyyôŸQkk£U@Ê(¨ˆ°צp†ðå·ÃÁ~¢Xjû;D!Ö#/,"B@M@*#$Pä@=·|Cr«˜#$pF]#/öâ¡qQ#,¬Ê#/õG•¯Þ¦º%¥÷1ºÉÑA§ùhÁSpÅ€åÓ™eî7ÇzŽ-žÒbÚ9‘Ýt+€v¶pÌûÁ±w¾•"f ž¼j™ ƒÁ›ÙÓô¢©ù} #$:ñÖ`äò°i~ô‡6)«‰£WÒ¡$P¨)Nááó¬Ã ) ¢¡š Õ‡@{Ç®ÖhƒùmÞšdà<Up•w%DÈï.T‰Ã•”8‰‘¤Ujƒð²É4ÇtÙ’žUlEôHšdÉß“µÛsÍZhñèîvgìssÈŒ8"s˜¨!š€´#,TV(NASeôjªÖè+Èämμa·4}o{žVv³XÙˆ¢È¹»ÒòFûêÌ¡â“ê“ê¯ô3åDŠ§²Œwï~Ò§3Ž;¤Lk#•ô×Ô=ÑU, ûbË!·GÃœ½Ió<ÎÐ}ÛR1[ '¥|.^I#I1H5$Ô²Ó¬’”ÛXÕ˜jaTÖ˜ÛjM¿q¢µqœ×CF³f×[éßrÝÙé7¿V^`s)pé‹&©M#$ñ7ÏÆ›h¯mNCM‚Ô¥¶‡š¡ÑŒ;;‰&i”ìLíÂÐ 57M'w G²•Ë¹,:"l ÕÀÂœqx4¹km ëEƒ·ÂF#,É&F[-ß]\g€{ÎÜq³!´€Ø:Ò#/M )kƒRÛ9F!¯)è•ÀˆA  Cë§Í"œåÖSˆÜ€¡#$PYl±’Ú!V\Î9“2ëCcòÔì󊛞õCÓ2!ƒ~à¶-V ø ¦VEsv*5 ßÞ­h`±f-V°àÚ_q`3÷3[&2ÆEô²Ð³cð1#,Ç") ‡—Êw„¸Yí+¹gw4 )@vý* tÔ"Á&R:X*zö™‡€z/~q“º0ºcxTNA¬O#$Š##Æ#$Ž@ U6<ãÊécàwæŸAB^[oòýV­ÙF]˜Ïº‘СÁ}-ÈÙ(¡+Qµ”Åo{‡æ>âžÿwÕÜ{8VD…»ŸÝŠ/xžà ßÎÝ÷¤‹“ÚJŒçã±K€kÖùÍ#$‡ˆ ‡¶’ÍšøÙCGGc—ÐûŠ*#$ÜhSéŠk ä:¢A'0“º‚åÈÃÃËp!,â#/ Y ˜ÌQ±£I.êè$6F™_Gy‡êîÚå\Üç¯7žzî-œ4VQMÔQF%äÝÍt#/ò6M¢«ÅÍrÜCÝݼ[Ï+´­)P³¿ V%FBj'êH¦±„Í÷íú~g¿ép ?}ÿšŸFTþ!ﬕ0O#?¦ùÀ0§˜Ë¬:t @Iˆ±bŒT—Qð6RcÐbZld**R66‹!¥™*›6¯·ñÅFúµ_¹¾ƒH(Ñ TÔmŠ£iJR$< #,ADA2Kaù ˜`##$ ˆ™|á)kYêâ\]O#aMGèäK}ÉùUð•ëMÝsdScXZʱF±³#Œ¬TÊ-– O^w¶“Z•6ˆDê¥Ñ@‹¹F€/n‰§û|LÞ]„ö>_Gñ:±$ê÷„V Þbö ñøë§?Ž¥;àK!?7\`$÷‚ia<ˆ=Ä‹v˜ô §G,¦‰"÷žjžýIŸ¥^Ûý¸Å…Œ„)RtiŸ1þB âfçšL ä*`,F)ˆK'Ùrkå«×p¨!x#,³#,OEMJ?ƒDÁæžÕj„‚òA#/Rœ†ÓF‚‰"‚Th„DÚ“JMRÚvœ·W¾í昚6Õ¬˜#$?¿#,(”+и^T§¸¥Y»Y–^Í zzÍ|ª‡Û ìF)ÃVxÝ¿pbܵ™€­*#€Ñ2óP¶vf¥£¬m´‡>t' ¯Á6 ´Ú ¹´;m^‘ß--òlAþ:=êå½áÓ¤½yFÆ?ª’8æÄ} 0eƒùXÐHX÷"½?åWû#$ƒÅ]5#L"Å)¦%I²5¶1R`¨ªM¶´oÂÛ}­^&ÃEh£i4ÊaŸ#ow ¨ËD)#/¢FÍLʺ?#$¹²Æ9T(ŒLXQ袚&f½…‚À K»P›á>QËrì×/mß–Ú[[ø*EkWš±­F- Ú”5F„«6X‹Xµ¡c„B}D£Ì᎞é¿ÍÛÛJ¬²R!ùxßî¾3`~ºÇúc )p¡4¤»ÂŒjxÅݤº| cKî$ú{dU¶iGlüï²Öm™bJ8,,‰ˆ"rÍÛŽðÉ€ÜQD“„ñyb¼êºoo’Ýf“SE*[Öl+¶Ùk»²¼kÍåkªmMoJ¹*-æî³7feW\ݵsµ–ȳjòîÆš&×wWw[I²¤©‘)“hV@U#,V$©ÁJ°ÁÂòít7-äMäÖ˜Eé½yq©M-”Ô™e^•®­çW^yÖÛÆ£YFS-e²–¼îå»]Û¢Ë[.šé+–»sÚðÝ28x€b¨µB˜úÐKa#,!€›4A?h×Uf…Ðj‘bɸ}…ð£!ãa0Rö´lÏT©¶®~ •#,¨þ}4™KhÍ¡ù$Ê AT.^ôI7Œb™™°rÙ†8c~ Ó^MÏ-»çÉr{uþ×äºpõBK°’r#ÙéÑ=X'la%¨‘#/ÛŸº÷#Eí3É×È—R›`‡TkÏq.$-ݯò|2 —C2¤M#,UJœ]/„èαoÎ÷¼#,1¦‹}ž&f¹#/v}ÛyD"Š8®QHÎ%ápo¯Rcx¹kõÞÂMN‚$aTÜ©&Ž>9˜Ú¬ˆ»¿‡ør’_á#£4Þí#Z¾‡O¤•—uÒ¤õÖö1üˆ¶$à×€H0l1¢7!¶dI§ßô<äÕàñé¡}M@ðËd)™&3/…Sã=MÃT¡óY§#‰I¥ùš¯C"JÝ',=ÓÈ®‘ßNáâ0ÎFW£ÃÍ`”)ݬú%‹0'œÜ Ø#Z V“©%°TR7Ô3rd5&G±:ÄÖº0ˆ@ëÙ©˜@Ç‚hvÉf}=ð+zC‘bøUÒ‰ŠQ¼J–-‚%¢–›ÕÕ™Öÿ×8kèú±‹ÿˆÃÚìú:9v'WwN¬òs¨÷ùQ“¤0é ©’Ñ% ¹¹8w8')©ºþê¢XŽH=žnY)a1Ο 궦qBƒš¤hÉûR\µ öÔ Ù;ò«[y¶ Ü(dÿ‰BÌ7EN@Ä®”Dqx‘·¢ØjtïNú¨T#,"ÐÍ@Ôb´¥àp1õɳy®¡¢QQ).ÖÃ@ÂÇA lÇ¡ˆÞ–E%2‹D —æx%Î\¯†E¨ç™ #$Pl~&NxêÍ?ôç̪÷°»@HHöšد#¡Àz B+î…œŽÓÇݘ€ \‘‹5ÁlDXÍ-ïMž¾¶—•(Px¸Š¨“ìÂ!h@Aü"eðÄ &xÐ[Ó@(ã 4†Ô#/<²dëúËB6WŽ¸ì ä÷ä|ªý€ûîýû6Gε©œ’2¹1P˜þ«*¶€Oý?úþïÕöÿÏÿÓþÿýŸù3ÿ£áçìëÿÝÿ£þŸÿuÿ÷æÙOû:ÿüÛËüÿÏÿßÓÿÇÝþñá,¿ãüåþ_ò×ÿê_ÏÿoÿïÿŸóîúÿç?ó÷ý\?åÿ/“üÿÏþWý?›øOúøþùþ¿ÙË/ðRCì§û"a â~ìOúŽÐL@Lgé#/uÅ1 Š¸úäE7¨;H‹ƒ»ƒìŸÙe#/ßC#$yMc#$ú•EK^÷¨·yüËøsôw;º‰$ 34ØŽ‚ÅN1¨ ªÂg«ÑT¨qB ³M¢ãÈä…LŠp ZhWz?ÍW–X–@N±ÿFíÛÏaAsHX¶æð#,¶àÕý@â÷EÿH“ äG^º*F  $ñÌA)§™˜`;u‡ò‘(Uòh$×v¸æû2üÆW/šÏë¿>7ÃÈ÷µMâzzÊ<5†/2­«ÿ•#,Ì´ ¢Át¹ x!)3 ±¯œ‡ýɨnÁ‘ÞÞ8ߺÿÝ[¬£ Óã-iŽc¥n²3¹[3?``Ú•5$C[#^½ÖinÍŽ8ÐÙiÐïà•0c 6áÁ£D"™U;Ú7­¼WÖšD˸v0&î¡#$ѺhWµ—R Ke±‚TK,>#,<Ù”Þ¨v á×ÊxøqísL( Ûlr¨3QQB±i‘4H]µRa&ÅÞOt³ad»’ LÖ¡·ÕçÕà«œÞ);¹Îˆ!­6vuaËá²oES|ê;6UNg1'‚"aæíÂ]Â’ !‚®W.ãÍïÜømà kÁ„ª¨´“<®€íþ?On|Çî¸Ñ¹=BÆu™¨" ª³ ¡I=8òé#1½ül`#/°Zd†6á¹R¶Î*ÒÅ@ñdŠX”_¥›U€Á‰ * §¡Ù:Nœ%¸J’†6i{Æ?–\FfpÿöÅåËäÈ/ÒÁËi;uÈ ˆ„˜qÕJ†Ö ™»3Ynîu¨Np„£Q!YH˜Ô/‰¨”5صf”ʪ6ÉTfi"E…‘S_EÛWUUðøu­~³®Óï>áÕþhÀÿZ¦è«y‚ÒJ/Ûî_‡u^Ï[ªmšÚ½Ý>€ÝåÉúOöHÃ8/×-åo¢×Cëuj.ba™ÿg™Ï¼~f½7*©ˆÄQŸP•xøõ¤ëÿHワí›Õï…¬äúÃ$tÛ%Œáÿ忲†Ùõ ÏO²zB3–9 >¹IÚÔÞŠï…@×–f­ÜT9†P^]*zgâ_£¾³ò‚Œðf™Ó%› iSG†o£Â f£‚0ŸUˆO¢áG½\áU±´[¢òÍe¯¦›×æl¶ƒ)JotÆÜ6_” $Â[â¶ù۲ƼmIo¼®cbÑðm¹µŒoméF¯e«zš$,‚©#$Ò0… RÍnÀ¼Ý‚ÛuÂBƒ‹‡$9¹bCf˜§Æÿ”…á·…8IÀ#,¦.D·Ge‹Ãvâ…˜P†%<¶l$½úÈc,ÊÕUªFFz©hÚÄÓÿ¼<ïÙt]ô¤‹ 3hä)_îùÎÞï›(ôfóGj:>Î"øñ(ÀOç`ÁCÐ?F¡þx¢ÅˆÇb;NÝ¢JP¨°DaÆ%P)‚`ÈEˆB%ÍH æB@‘I E;½žï†G—Èú>hiFBtïø¡ñ}}­wÑÓNÓ2ùYiû³ˆ ^!ÃGF åã,A‘;þßÀ?>ÿÃÿP …çý}Ÿ±'Aáž'ԂȤFOý¾@P‹_ö¸sX[þTþßõ< zÈbe ïÿØØÿÖôÿVÛùt‹<.Zþ~Wöÿõú¿ð»OŠü|!óa§Ž„æ¯TrâCΗuÇ™ïøuÐw¡ÃàÎ@{9aw§×èä8¾#=ã’ÿî°y¹#,_úÄ+?B[2D?_÷ÔœØ~ç¨~Ë#÷i‚SþÉ+u#K7±r…unŸÿ^ÁŸ#$Ê =þvbã¨:'R’í²ÛRýôZÎJíâqTE3‚o³UÂã,æ#,L;äq¦Ó§m3 ÊÊÇîç,Má†/-„±¿Ñ8¨–¼­§0ayþÎ$fu‹^;ÙWñzÝvd±KÖMqAuõû|‹31éÏco#´Ÿüý»Ÿ#,~Ÿø«#ħ¢ŒäÅ#,¾ÓÔbI(P‚5Ö®§üD*žÑð{¾¯­" ÿþ.äŠp¡!£à¥z +#BZh91AY&SY5I x¶9ÿÿÿöÐÿÿÿÿÿÿÿÿÿÿÿu€ †¬ 8ÁX0E‚¨bQ<{Ê÷Ü€#/ #/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/´{é׫m½°MvÇOcÝ—±Õµ«"P}ïv’w·tßvìØtÝ·Óîz8™gY³£ë'ÞÞû_s©³1—lì®ÙWJ=õð;Ó7}ݛݘ/[{”ÐuïuÎl zÜš+££Š†´HÞžÊknÀç}w¶Õo¬úõy{æï¼ãv5ï4uÓÏ-£Oi»­ç{Ý=©>=÷[Û¥öݧ€d^ö­×w7ßg¯#/#/#/€ôØ#/4§Tpy=Eï#/.`èu#¢Í’·£ÞÞÖ5°i #/ƒ6Ûnév4É)Û#9êŠÖŒ»a¶‹Mt4kE]†#/ ¢¨”¨ (¬TJOM@#/J€Ù•U@E²ÍC½õ•çºÑö÷ ä§{Yë¯lõêïníXU›HÖUîäÖ%)Öûï\³QIOwAöòÞ7·uißZv3ßw¯Ù÷7¶É•E[gwºúÇ{¯½Ôóè’Ek³æûw“æÎùœÞõèw»×^ÞÆãݶº#9]"#/¥RAÍhnî•]µºîÓ«§;¬v{¼ôÎóºW{é]µï91»™Ö"¨·n´ësEPP#9J¤@ªVC׳•¬ñ{ÛÐNÝ^ºîÖzä¸ôæö›[»è|ž|¾ö÷^}‡«·Ð›ÚZ6Àë¢ã½Ú8y-ñÝU'¦½õ¸#ÞÏy“wxç½vg¦æšØS½³§Ï{Öï}æù÷-Ýî=sÁ®:y{­ÀÙ™š#/*o®ZËlÉ=}îó@[šyÙ|¾úy[-«»©Öîînv×Ö›{s¶I&Õ¦ÞÖ»·[bÜO½»zÉooíô¹`¥ÖeÒ¹0«¾¾Üú.ñ½á×OˆîomÞÝžöU{eÝÜÛ»[×¼t÷M÷Ô8ÙlJTŸ>>ö'}»­;-ÜòzvLÍè[ÝÔÞ÷q¾ÎrÛ몘㛅·#9¸9ež‡0#/^Jõ{Îó¼Y»î¥·»¨u¼¡@#9)I¢Bº÷iÝvÃœ‚©»†]š,_x£ÜôÝ/MÙÐꫯ^C¯,¢óMÑ·6´çN¯¼ÊÇvo:ëY;“½Î×[»²ð#/ÜçT*#/!sèûízû·w;Ë]ò:ìÚ}·]Í.ætd¶rä}]dã¾ÞåOWcJ“ëÍéË_ѵ×ݯM#7©œCu6ÜAï,u\‡¼¾çÕ}ëÈîí]73À¤#9hv5må<ÝÛ·®Ù&÷;×7uvdžÃqW¶´iʶ÷Ø=Þõ{ÝÃ5jÜÓ¦Û»»¶Ò»—o{‡šÛ×hîqôv½Í[õå÷Ï®ßnŠîîc–m¹š+èÛÒ­œK¶ì…xžì8ôÈ«Æù³¨:7a¦[­u}µ9o»¦:ÑuµµšhSÞy.Y¶¬úèú·›onûÆñ‚¥Ùׯ_Gvöu|ãÝÝg¼nÑ2Ë_líÑïeÓ™ëÜîÓ§J=z#/8T#9Tz‡vÞ{0»mª÷:ç¡è9y LÑ€{ݻǜú2Ó}oT#7<€è#9Om[yÝï(#/RæÛ5¹ª÷ßg¬@iB¨(U­JîT)zõ€]S½Æñæ&εÁëÔ3}ǽ·®ºÔæÚi›·tfŠE ·VÅÙÒ‹§1U…WÜï·ßxëi´ß,íl-¬¼· éÏhš²nùί‹'yóØÞ•g^xø'Z‰'Ó¶¹èêö9vÌí+Ý™»¹·½åÊ¢ßw]÷‘÷}÷·:ÚÛ5wvs»<^¾ß÷Ž¶À¢ñ.&¸4Ñ#/@#/Ð#/š#/ša2 ˆjõ‰uÃæƒQê‡"©•ñr[ܹÈnµ}ÿw§25gßס™Ç0‰ñµf[b#6Ý­æÕ’EPÄ/³X {zႹ#9m»®QéÊ7Ìí|_;ºîír¾g“x®WÁ\Ѩ8šë•ÞwTnQÒ¹s%òÔá¾öÕçàD²kš#94±ˆ‹m1™í²àÀ0{Ïf0Ÿ#â^ Dæ…#9ŠÜ¢¤E±È…´3Ó–4uɨjÅ‚¾ú)Gèa¿Úᛜû‹>çíÒFßf dÿ~££GŽðµR#9€Ž(Ÿö{p6¾‚v²´ÁýˆVÚMód4ëÉ0k柟xjOOÃ(Ýñ|çÌhÁØ&Û]FrÃ0ü¢žj¹ƒÆÏGQ{ïø-rH ÒSSòjEE#91pq,Ì\}Ûñx®Ãíʼn²Õqe¦Ž ÊNn¬îM8‰²Ké^ë® Ê•Ž˜ßÕµçb‚¼(Cëe ½9ÕÅ)ñÇÕ~·= à`ø§nínœš}l”‘KR†Jv,E¢p|sq¿ ‡ƒƒÐ?{&EÙä²٪‰í3 ûl§,Q£S%"V}±Æ/‹öb§b¹d]T²ª ¨}ÙÅÁ¤û¬¡‘´=È°÷2¢¿M>¬¬,‰±Èj[ÿ9«íÛÆ-éÓóašLY|Ýuõz¡@c¡ò ±#7ó[bV¯¢#cJDѧF^(q¡Uˆ9j˜ð©W[:]¬­|kü{*gZP¨:Щ()ra;NCêPÉSô}¹¢=y”—“@Œ†ˆRÅcå¿ËÙ¥`ÕÊîÄ0*j‡¿Ÿóh¥&Hšh©ME'Çß¼oÞ:µºnœ·0wÝÄDÑ:]e* „¥Q)—5mç}ëÕä@ÊU’¡ð¸ÉhJ¸Ã…‰^Ì2šR §Òä›åëßãëx§¿wG\ÆÆ¢¤Ï[ÆuBQCò°ªŠJ`&±=w¨‡·Ù¦ö`=ÉSe…²SLPê¨iÌ Â#™­lÕŸ‚I„‘½¶³Æ#9ˆ% »ìC”a+²íç£[X0ÃBäFNO$¶ÃmE‘„ÖBuµ y³!L®÷`dó£ÁÆÉE2„R]U¥"½;êÖFþUjxhRÍõðÐÂœz÷Y`Å„àÓD%Œ0£œœˆ5¬”ª¹=µˆ%]…•%Œ7g´›$Õ—o—õð‡è(*‚Ì£ø7fî<$›éG÷ýzŸÇm7ãÆ#9A`£×Œ8‰Ê¨ó¢§Ü’¼<,-UBÄN”Rv²”Dp¥ÑßENQÊ©êüRý´üªy]#9'Ý},ã¶Õ 3Vpzc{éPùT©†.²ãÊü?ÎçκCiT4á(kÂC›¬0âMú~³ŒY­4y4kM-v¥I»QT”™…‘¯:»?/òw’0_*ÈÜEØ ÆK¯oþµm¶žY‹ìöLöD§“ 7§“F?¦Iã:°Ãl’Iév…å¡ój=É›:ºb“…~ª¡ÄËÒϯn=l®)]=3^JCø²MX /szø‚i·ŸRK“oô1m¼‘†Hm¢Yñ°ûòÝaÎwÔ‡ék{ß?íêµËCÏ’ñ’"uN 5C(ëùÙ³¨óªu)Ҹߕ†\(œš?FP§‚>wÏ]pu03‚bå'#9ëõØZõ|æ¡}Ùâ¹/šuBÔΤï™ÄŸ_{¤~þp^´žhý{a¡*‘Ÿ’@:@ú¤â÷Ÿ6uLjÊÙ !aâþguIêÍU&´¶Gch±y2ŒcâãXÙg8qÖu&!/²q(q<åÁ{ÞÕçøs›«ÞÑrôdn®$g ¦[sÃZ=6÷—\Ÿj¤hDÆY»aà7çÖãz…U„aî¬YLéßV»*Ò„˜p"GÙ÷]ö¦FL•Å¹ØªThÎ0y½B’QH£+˜\ÍʳޡÏ\ÉÒqxÝŸB¡ÇL!À‡w0Œx¹Í™àémP|×l¤0iPûÛAn¨ÂÊârDþ2oêÍb5 µCnãSqãʽµÂ%NS¿/åü÷¼QiØÍ»ÏLP_>åL’&¹†ìl~Øtná%ÛˆáŽzR <’I‘Ð$ÕäìG£ö±ÌWÝ¢d"§£A’-k²c ôå­Þ°ÓYù¡S£Aý×Éê#Ü4XÜŽ#7ƒ@ßYF5ÏÙU7‘³?¼ÝZq>héa¶RšŠÞÕ^žFÌ›Éý´×úTÔr~…PéT$4k˜ñ(˜FóeõªšgM;óº°90(ûh¤TWôL ß³7J*/Ë`"Æ)F“[ëqØE¹O›sF3ìèéæïÑÆo›h‘¹¢(2œ÷ï‹ßO£Ý‹¡#GŒS#z´:E·ìˆ¿=×gú°)TùøU?mñ5„Î'}ã—‰]½<$ù-¯´6êd2iF£u´»ZrvfdmýÍFs»‹ÁáÓã¸AËÚë“,be¨ÎZNÜþ&;:m°»W =/º©No¥TåÇ0·‡˜~líºÇ°½è´"(>¸t\:çx1TS–0I×ðqÕžúªCÉ›æP‘AGTíÒ±©’û¬¦rTl\O·GÒv³$3Â%FÛk>š¨<‘ç¾Ðk£Õ‘Çy¨¬ÛA ë§g‹ˆ}ôéf¡†F7v2]{l9NT1]¸†"‹EuôÇ.U—J8Ùÿf´xð¨#9h6ÀêD´ðaK–R‚±7gFTd.W=uëá¸öðÙ#9ã[#9aȤuÙÉwÄgÏ› K2êxßìšé´ÿ¦_òâmüãaçÌ­ Þ§x§8vA„1ÂvOì7þˆ.þ»±ºxWä­û¡Ú§~/7/Ä9,J&‘ä*$‘CE#9¡ÃÅFAöÞ®Þå`¿F¯ÕR“5ï½Ñ<¡ÑéwŽúøºgÐ$E# K‡&±ugcÐOù¸^Ÿüîõ\ïÇ9¡uv ÎP´ò˜Ðé3“^[ûíÅÙݦ𑬆QŸ"åkElæ#Š¤:¤*!šãèYò=Z°PŠ*ÂåT#7™Õ)öžkzW‘¤1Š×_7nšj½ Ž[CF}˜øÆÃ݃…öYåêp4„R¡oj·¾n\†çfåþ =I†*PUH1=d·#+–Ç…€(±P0Ò¾ê^Ã#9«Š©–÷wW3zŒJI\uúš7Ò/·^ßG™×Ô4±ö4¶Îjø%qÒë•~.tM^.k2(Õö@×—ï\ñãT#~éË+×gƒÿ•8š+Ž®›e;ŽÒˆG¦ï¸š¶éZïCÛ¢V%ÆÀŽÛöðæV{áeX¾hG:øÄ¢RïqÏš ï :ò~•U1žÓ!f  7K–*^üJ¿— úåøÍ(æ‘W¨ê70þ‘ê¿ž\Çgôæc\zÆS|¸Î©¬W¯NéÊ£W8*piø(1DEÛôĤÿíÓÏázpΰûž?NGó÷f#9•ðtáþ›#9’,0ºÕÝØuhé©í±o‰c‡ÈHotû³·æEÅ|õÃÛîQr‹³Z”,ª£–.O˜ê§ìç¶1Ë™÷ù|¾›Ø½±A#9s]·^c40#K·òDƒçñžQ›q§"% ‡ í4Ø{Tn°HÚ‡I4Jr ;‰'vzwÑ_J¨©²í¯“/Ï·1Áª`r$ÎÿÓ– (fïïNQœÇ:uºõÑCÕûY6Å:ЫNØ£=(–ÆO9¶Wwm®žK¯LƒCmëV—Ùøç–—žði—¥!¹~Ý|oºÆÐüfßžGY:ºúõ‹‡ù»„*IŠÓ{c¼ˆç\çŒF‹‡5ÄFÏ%e5 öMüÕ"“Šu“ËvƒÑ÷'Uy‚ã{’Ù§Làò²€“\ÌÎÁüá´É2!Nî5âäƒÜÒlëÃJ×``¯\ܽ¿ïÁæiG‹5‚£"Ïñé›{ª¢rÆ6uTo%‰ŽŽ}(4¨ßXx&‘O—€,C²aB’, y2Y”ˆÓ Gqš-ñ:9Ö!­ZÉF©âèÌF"?Ÿw¿w&]½™·zsÇc£ýJV®OeöÎl‡E[”ðk°ç\b]#9Úcý$¯ïE—¯Iø£öKkç¶:Ð~¸ËSøaðݘǒ7ú"ðnþw¬^‘AQñ Í¢†nÚÄüéJ~ýi6¬#9ºlã}zQi Ólª«Þ­Æ+”iUˆ¢,õ+äà&´È¯Ôá?ŠXOÐÀ£Ca§É \Y@sãg»_Â×ú{ì öQÜòåžihŸis’ÒÆèò‡hµ¼)ÐFz$‹ ³“pÕ?l?P3ϬAÑ47\Κ–¹é4íÊ£‹5™AðjÒ:¢š¥³–Ôqz~•¶°ýO#/C‚n™¶Œ{k(ËP"1b±ûlņE,VѺ›m-ðCèÔ_+#Y.°Ñm3,+ók¨ýnsg“:ÔÀÁfõU«E+m"q'„3#7–6\j¾uª$ ]â6O´OE_'ÂÝû¹î‡dƒ:P¸˜‡®¥ß¯nœkð³Õ—_$ºP‘áùÙ5˜ˆÚõH¹Ö‡*ŽÅŠ»Å2š¿tœaÎî$ÆV–^nžQ ‹ •.â®I;Aý!(þ|éõcZQ48Ìnüîã#ÏÔªXª*&¿•0^€ðj#7Dæ¤GWg‹Y¬¬b¶#ãg #711­ñp£0p¦‰ÖßNÙ[`˜ÕJÊš¼vîÜÞ'k‘KŽ«®1®å¤ªh‘ÕdŬ­~ŸÎç#7€¨^9‡òò`î(wØÌëGxû’|#9’IrLŽYC·øIS« dŸ€Úæ¾0˱ŸT\lA“aþÅO]Ýžñ'­'Èð#/A¤£ÀˆxÛ÷:éüãš#7ê.ï×V¿ýý;‘pÙ…ºÇÞö ‚Äpžý‡`x¾ž¡´rd®h*QÅ‘˜7’ áFWÙé?íú¸ü‹ànþû69F¥<Ê7mËÅ"ßY1Ñ÷w rV"ØÜNÔLÈM¤x…ekm$}Œ[i-µðaæú¾»›d8Õ/»ouDxúFT¦6M›|²hA³ì¡œw&¦E8uŒÁ®[Â4íŒ95jþÚïbÔq‘½R#7µ¯Ý§:î-¾ŒMŠNwtüuÍ<$;"°£QÐj2H€jUñó2PŠWÈÈ°Q,-(Ä3•2!ˆqK,YÅ[Š¸ÿ™÷`,·æTúL=+6ù#éÅ8ßÙ-4]/jiUĺ™@1çøö>v.5bÕ£CÞÛŒ¢#Wqò*3}o×7À>çd|ú#gŽ ZP¿m»\ˆ&ô’ãY»ø@B0/ä›H©ÛÛÉœ·Gÿ#/„êâQ‹^¿]«CÞ )H¹[걑†“3>w¨U,ÄMTaq†«#ÝøLíc€’Arî-CŸoÅÎÒíÎbþŽÛMÇuÒŸ'Ê[HÕÄz>%üÞYÏ ãt(2G ![ë„q¯}=5ùî”iü­•Úr ‡'^nŠg®:µË0=½¼½©~þ…\8¢ºWìåÐÓ“Qʦ]ßÕ½úÉ#Ñf\q#7ÚÜ Lé†ÙwM#9/Zbµ7îÈ×+ãÚõ#dºá‡nþtÛ) ©Áݳú:3/UW«#76ÿ¼T•"³4{múfï=ÕÁÕ2ÅÓ¾¡pS²¸¦q@Àò£™Ô4¨îàúåß·‡ñ³$âµà(ÌëïUFÍ7Px[‹lÐû&þ€‘~¡Ç@¹¥!ía4ýšQ™?»ô[ƒ~â”ÃnaÃùÆqñךð"pg#935JöÁ.ríFÚx¥ÆÏD@JÁƒ¦2ÏBdÉ,¨—#7Ɖ>Ô³h´ØµÑ”£|Ãœ£‰LÄïÄå È •JQ ˆ–?tÜ è!N˜­ÃÛôME³ñî~쵺täÚ?N*ÏZ—eËk`éqù¡+¡h"[N]EU8‰šÔ(±—Ï !ên­ö`ø ¤ >ƒÎy¢yX?È·>™Šèÿ#/dS”¥„Q eò9j+{x$T– þtüÔÛ˜ÀB‚”«¼ZÞE˜6ŠÕíýÚ×\éí½EÃ_»70SìÒJA#Û€›Á‡—ÃŽ™ömÿ¦9wQ:¨‹»àÙó¢zLmîéÿG—ŽÛ)Í‘*÷Yþb4ÉÖÌomÈ4 ]µF“m'€êÇO¢cÂ#77ŽÊ‰Á`(eô¿’ŽšÆTrÒûJ&ùâs6iYκ/þ ÐŒŸ\töPÈc½1Q¾û˜ 6Ž–Fì(™ #9¯ŒNǧ(ÿ_w^½¼ûé†Þø»?¬ ~þ¹ oêp  $Aè%þ®Ù Oî`ű†—ZìV#/ÑxùnÙTF7IGœ|á¹.…Rœð%³Ì÷ ¥#7!pËR o±;€À{$,õt«BVøN­ôò#/‰ÜJŠØ*#‘#/t"£:7”cŸ èm%ãòp}ÛK]Œé—vªõÀ¾†5©µ^1€±D©çøñ¦1†‹‚öM‰`f'^¼œge÷âºu|‡ì×iþ%eû=‘øý²¨Œ§G°Çý_ ý¬äÀç@@Ê"%H(@)\‡küüð¼#9¶ýh(´£M[T sA²H}>aß)|ŽU$´ª{ª’$=îú_}†È„.ç5ÿÄ$€Y’AÏzùU#/d¾É'b»X°ÏFHÐ4Ð+üƒ[Ù’Gµóò;úvmi#7§d‹œ¿>|GÑñú`/×mšEÿäoÏÓµMŒÜååµ.ÍÚÖà%Æ_ºù#ë:iÛüôýáÒ웶×uG'OÉɾÝ×T;æ}÷ðåQõúJ¢Vúúž™âž?ÑìwSÒ(H„ņH,×vbb"3Ì9 ,ﻪsîà¡ÈTTG€¸¨Ñ|V#/r$yñÒtJÔr‘#7¸ý§ðã“êx¦Qé-åþ(!qž™•¢]í¤„3x®f”"<:]>NYé«c}Pxß ÃAH@¹ì5Ù¬j~rp¦F°ôo:.Xÿús-#9!Îå#9#9«|úsO^û-ù{û?'I™#/t÷X\]êrÊ°ìÝ ¤ÝaÏ\Ö†öøæ(öw¿MÍ ?1Í„#/Ë$”³Z¿Ä|5aa vx• mE´Sa±ëLcòžqç†0ÌFÙÐÿ?La!cüúu¹(HFÖ¡ìñZXƒÉJîùÄ\ú['ù–°<ÉÑžò%)³8ëÛc ´•¹öpá"–§Ó{ѤذŒ4øtü0nµé–Ö·ƒ”N( nœäë!Œ,4Çë§ÏBbÞFL¸=Møñ7¦t#7Q4q%AeÖÎ5UUH !I-ßÒÙ„œjìo£Á}±èyœ^Žæ"õ#7#lFññ°Óx¶ŸÂÁ2™ˆ£1HSXèMÔ?¢´¿m#/©IlåwÇܘjïk×;Øxâ9^ ßï±Þ`ß“'ÕrÍ#‚˜Nvü–@Skš<³©Vò ®øìéý&Î|‚Ø}ˆ Þ˜r„âN[5Ìú"™ \¼ÀèŽÒØþîÕ'¤é¦<ÚHÃÛɯ¤1SöXЉéZ.¡Þ=#7úf›Ù0mê²!5-S8-ñ#4“\L1=#óývQáûº¤a¹ß¼¸ü¹¥¥lî;>å‡wg#—BÁ0Ž1f$Fª¼Ã{òŸš›ÒéÌò,#7¤:vŒJgiãòjBI/¦L}2ìÊ8·mêÌt‹¯—#9¾¾ØÐ93z7ÊÓ¦ªéH)´‚ðDˆ,yk¬íK}5V'ýë?j0Æ7#9#/¡›q#/Î0ĵ{=çÆlŸãŽ0=3›÷˜$àvøyrYøÁ¦%CL9ÕžØc%.ƒ¿ tTã ‘Ø+.¾…ä~Èì#/l ‘§Ñ0 äi‡…àÂåÐ ÈH¡býZÑx½,@SH.Û'Ö±©tXk²Hî5â ÂêÛ’î~ŽÅc¯ó}¸V×ÔØ!¾®`XžðPŠLP°"­Ó=žý+ÔÔëžgšá•¹[Œô:Ó!;/EŠ¸¡|›C7¡¸-$Æ4ØzÐ^ËÎþÿ¹LëÄ<„wi¸hrNR°fRµç$rÆÆÔ²#7 Öb1(™Z(ÂؼvqcLK#ÆÄR§¥LoqGd`Æ1#7(0¹\Ì+!a—EÚÿ!»ãÍõg6o)£‚iOïÌ 2š÷mCÚóÒn,xF1#9‚,"¨°wøÓÓÇNÓ¼£žx#ExëÊõÔç·³ùª‡ %öoÀQ`À8ïÔæ GëÞäç÷¯˜òz«<áÞ£#7s#7Ù ¼7Æúe>>­´O²y Ñ#/åY½Á®u! …‚0&$%#/‚0ˆ‡Û_&d?‰|5÷ñ§ëÇÙjpsï(½Ÿ\<¦ïµÏh:QJO"œ´ÍŒÞÒ!Åtã~‹fÁbƒó[U¤’äJ[¥hŠÁ®Qx-@µµBe.Ë<Ýu¥ÂÄ£(0…ׇA &tjÊGWñìï^wãã̦ñ}£t×c$'e»6XDPRrÕ6`ö‘\ðÄ\cå â,Mal$"2or>h ~KJâìjT öbM v©CÁ¼ã¿OÎûDñïæU÷o\b‹˜ÇˆUœ{ªç»): ô*²Ï\‚6éÅ,áTŠ#’ÒšêœIxuY×Aûpv3ÞÁðî­ÇXïß±sew'ðöãšr<Îã’[âݼÃa&lìvÅ‹›Èk6ãÓäÑèXÎcDÉ¡ÈÌ\åꦶZ CÎØÕGërT¸Ü(¼P`Þì®Mçm{ô–zW•ÏF9hŠR8¥c—<}|±-h÷5;zÁÆÍàæÒmßuóëÛcÉz`;¥·Kº`Êõätnª5<⬲mõaE“á/k¼Qxän•êÂHN]ÈC ªaîÆÄú¤ý?¯ØÒR‹þºÝ-¯{awúsA*|Á–@Éè´GÑ ö¬ȦÆô.Š%Šåêã M#ÎäÖÒ=C÷]FÐÐ!?BŽ¢çr”±Ì€»¢€=Õ#9Í–2[B((¨¥ë»]Þy—k»ºÓÇa˜ÄF”j¥²™) ° k°éèé“ÔÐŒ;ôÓLßÛQ_.WÒj—Œtn>Ë„¤I‡hM5#9IÐÕ1\)Œi‘JÄŒéî÷kÝ¡4›ª‘Zi @#/¸ä²qÛ”w†´Gøý;Éò~ú˽UÓ¦,ic}^U£Dˆ’6x³ú5Ø÷-šá¨m |FY˜ß̘Çj^XÉ“ýÎj‡4·Ãžh¸`á@°Š¡JÖ=öªê»Žk02é5ŠØ—fB€HV¹;^zÃD–Üs"Í™±µRŽÊ„ô>iøôíãIi‰„C&~Ϲ*O€òGŸhcF•o¯µjœîVÑüÇN“’–Ã\¯u“Žû„‡ÒÇßl0²A¬š,'#7]1k`én„0‘œ“Õ›48Ã<¼É~å*±‰l ˜ÌF›{?¯Wª¥°øeZ`anï:ÎÈ&ø­yˆÝ‘3’çE›jGw1Kr¡ºÓØÒC{—@Ç%s0R´Úl`¶êXïSHÁ“8‘ÂÒA–::ky6‡R䄽$š1 hÙ$Ô¼áÙ6±ÙBfÊY`Ù,E#˜Äºëß?v–v™5¶¼¼«ªÓBùöíÔo¤) ¡²IM©/Òצ6¯¶WŸªäQ¦F1bhËFÞÉ$m¥ZI°ÓAd 1ã±êº«´ÙÆÒ& 5N¢€Ú¡0 YH&½1[Ók_^ÍÓ僌ÎÌIþ>~þ-ÕkËÚe‹Kü—¼„¨D 1¤¦IêÞ&ËYæ#7í{—Û7éìsâ±æV>äø: åÄKõêíÇ|”4vû©M rVìûšWÞ@Ê,å€D$äBeŸHíAÍÄo«œ0 x ;xù“ø×öèÅ9·ØW«âÊ"nØå»k[Hæ]Ö¹†s‡ÊÀ„ÚhlËš_væ)táû2œœRLîõò„b#7älsbÔ\ÈŽõxjÆا¹_OjÃ\#/Hx_n«lDzqÖE2\ËJîkÖÁ`×h²;\Çöbë'´øçñí¶–þûiLñèám‡ ££¼å$$½ì{®D{eû!óºˆý§V}éÌNĘ^D“®–É¢| ¶†ëÛ¬p;䊳•Å¾$ÅY"•™tßU‰¼#·QDimøŸ-"øõÃ$„ ëYŽïœ“×2–bÇYð‡ ñ¯/³ö¶- 3.vsû±º‰¸:®û«Û¶’dÇpLy’@Â`ßæÌ¡YB/,ÊÂ$ÿŠ-]GÀþ5ðígPùN9)ÐþåF”;PG4_U²kd*Ã:M‘Ï^xX²áb'˜uŸ­å/mŸfýËnŒÜ±Y»é®ÃÌ™X1Æ­Rd‹TÐКaWGWH߯6|ÿ»s¤}œ+¤ Ç徂qwF#7 ˜85ÿ"ÃUÕRÓZHŒQB³U QC³²­á¬¹§‘6ÐÁªPžçD¹KQ#9rÑîü³_nœ1¶É^ƒÂƒ‹>‡E*òŒ`S‘ÈŸž~M‡ÿ Á¸Ñ à!\3ÊÖ~"®“€7y`¬9<Æ}ÌQµé-BJ¦ù½Átñ^_7of»íA|š`¦éB!@u"êYC•^¼&9iÖDœ›}#ïž‚Sˆù?u½ðÔ&f«ô¾2ò×Iž)pó;í”)KLJÔÃ’‰„¤E ’áR¹#9á Éb4äÐÑf!Á°Æ1’ZYiOe)xS.¬©é50(3 »làíÝä72Æ#VB#/#9…€“à”„PB‹‰‡ŒfR¤'Ë·ë b?!ù¬/j|¼äýñÄîäÐÅí¼8¹ ¹C@på[ð-¿hoÑÁ:øFŒŽ_† ºÏòêåÞŽha¤aÎ¥ÙŒ”8j¢æ‰‰ ƒJß·`ýÃõ¨ö³}j¶«˜õ3áñ+ºŸ!D‘i`Lè<ãøñøøÝø›R¥Ahù=¬,ÛÔÂ$iš„ý–ªnýÊ›æãt\4®q#9|‘Jã0¶…{—Ø'2I$Ÿ†®HÊgÏMܯõxÞÄ#7½ ïiò.¢-Ë*Œ#/–CÉó~Îøówvq‘ ¨ìƒ£ñ|£+aá´‹,˜¤@w-·tó]KÏÕgž—ýøÃåoG&6Ê]~¥)«ì¼O‚;aÈ~¬Xy¾NOßáøêø«^7‹ Ú{a‚qÊ#‰ðÖãäjV!Àh ÅÀªB<—¹&‰#/O.ÑÂ÷û:¢“‚øç[¼•It]$Tø໇Ê<žßpLÄ„€ÄoU ×½Ÿ òXF¥$LcM呪“¤P¡BDqØ?Û Ð:1’¼?åú¾ów‹hüT]V9”*å±fQãã^Å^‰œì»YM^­FÕ#7K\VJˆäŸ·÷öþ~­ HqCßÿF³KùìÛQ¾Ÿ³ìù7Ë‘#/D ?:( €”¿£ËÝuð±ãÚáÌù‡ÊTz1úÉ·‡hˆ›h).¢QXl#ÚS™è“øo]±#9-ˆÏSµ ŠfÔ–Mb6T±(¾õÆbhÓb¯Á^ŽÛµ#e†8Bd¨ížz®ÝŠ[üˆ§×P‡Å… oö‹#7ŒÞßÐé¥ðh£<Ù&@nò&‚‚9}-û@Q&ëðZþæ6¼ ¤­ŠL#9ó‡Íý\²Ød¦ui+†, A#9 ³ó¿#7o!’Ud¦a‚àKä؆}2Ø7æ×=§éïþžÏÐþ#9a#9(+!"îñÿ:”¿§ÇýO¯OβŽˆÂŽY›¢P4Ò?ß„\”¤óÞ!kóe?Œ¼ 0Ûº1‰+š'¯üxÁJU#±”T®ÑB<áD*˜’¨¡=¨Ãûü4‡Û>ÝOÍËÎ=¶5Q×Ó;¦7Lj#9 ›`VŠA@ôñàk_ìÌ—Úk gíßÌrƒHÙU;°W3‰Sÿ%]´Ûºÿ–i}M:—øOì‹ö©Jg>óüÊ%Ð]5¤¶ a¤­I¼ÕÔ½»ÿ¸~o~h’…þ¸ü_V†µZ:|_Éû¬˜?F|×µ Ä?yÖŒ¸ìwé©—¢û-Ä1Ç_86×ñ‡7ÝÇ\¼…‰˜z© ¦é$<곸ÀᢠmßßÚ–¢*¡cT+÷ýµÉâüÑð A}n&Q&Åûú^óh#9*(HÎ$ Õ¯HfZüfd9hem¯„û¢2“óùèvÄÐv”]¼°~ùpa?=ÒsŽW 3hOÞ#/à@í%RD?š2#/+ ã#/Á€ô¸)8ô øQ¾H¿kúˆõd5ý¾o“å?%ÿoíV#öÙó]è¢ig§œõ¿ï]>›ãù‹è!×/×?1ëùÀø„K¾“ÜE¤dSþfú¼„Ïc¾ÌÕáùhñ(ãû¿v¾ku³ [­â>‹€ê(ŽDó$f“{“mÂí>{-¬¬üzïu–ÒçJúwI<2~œT~RÑ¿¶ãj\…xüÿ(¥šÎ˜ù?ÜŒ»NÇ,ïw÷lçû›m#k¿~‘Ýצ+R-åTÊÍN¼#94Öþg#/l9h7ê™RfN0¡ˆg Îô†s×T(rÐߪë.v§9ÜÚèÿ“¯!”;«×W©Ar¦îI7¤ÀàFZ9ÛÄC`„Wµ¼¤"”,ZªPÉ-çvѼ.¸œë2jZÄMZŠs0hªo0âþà‚’‹ßmvöëtà|tÆÇØ“½ðNÿl ŸçF·(V,ýlÍœ/eøh:)óaI5ñǘÀDZ›eE'ºÐQŠ1`¯ÚÏ‚C€FL2 š4I±\ößöœ7Ú¨@Êc`€£˜‰ADdã1r—íÑ¿Î=~/‹ÃèõóX¿7Ðo>³…û¹û#V ƒ³ÓÏí4oW…š6¥žÿ¢vÛo-¿G7@ó¨û¯ö4µ|ÂßVN ã´_é¥Fe/[5¿U˧}îö²/€ŸÂ³ú±ïå?¯—¾wÝ#7ëðý>=Â\7ûçÐttr^%8ìƒz±Í²*%Z½·E~;ûÚ¥ÃÎ}^#9î“Ë';å¾4yØàÄÛ·?^‡!Øíñ_\ÙÓgøˆµ;«ðÝßÃݳ¿Ù£?1´^éÇGùº>W¼.b£˜ nëô;I§LÛG7“LÇ£ðEmËÑòÅÇV¤§êOwóœýòÞBŸ*@k>~Â+Û­Ý]¬ú+:q2áÐ+ôA9rù=ï#9m˜–©¡éèdÈy®[e#7÷r-”óð‹zuåݺå{ÙYè±ócY^áõ@c«’Žêöéý&×péÅ9pçþs¶1†š¶¯›¢\ÏUyvîÕ î|Ƹó«ßâ†)eÂ#7iâ|½)Fû;åm¥û®ZõÇXñJ.‰6ŽoÇGÄØu–k•¶uĵo`6óAF4†¿U¬Ä¼º8°ú#`ᥖëæLo¿X®¾A¹‚ÅÌÙ…¸4d\çU\Óú>=ê5rÙ£>]rw'«›“ÖøøóaåßÃÒwk&éc½Þr%îöp»U×÷N[ùÛ44¨ë î3^çìC#7 ›2úFŸ¤Ú 2´@ÖôcL¼Lœ.]¼q¾=ÐÙ9qi{GH–Uú<”uþm·YEß½DÊYñØ–|[èùºxeþsLEí¬ßö|}Éæþ^ï|©¥Ø]ùkmš¬£º³õDþ஀ênõOÌ»;¾&˜}†ZGºp˜Ù«)/VÀ9~.š~ë´F£ÐwŸM÷>¤Z8‘ØÚŸ“æ¯×êa»\—Ö¶“n‡|ŸéÅøôõ9´Gß«G%~W|Móp8ÎX€O%ðjycO÷|pqÝ÷goÞt2@a¡‘SVCËÚ‰ã7’v]_wÁül··ë´sïÓ‚|ç÷›è?qÿiîÑ·}—îŠf+Øÿñèöz¬²Þ{‰Qõú<þÓü0Š“»Õùuëü²ó¶–—¿ãµº{¿Çûª“ø ÁÑy[lcÒzÿ£çÜÖéýã©ì¿£ÍÞ$“ÜÈ¡¼˜ÕÉ#/ Ã\Cû¹èØVcõõ”¢Þf€€¢ó$ˆweF}Úë#7Ãiö®×ÏßùYõC­AÜ>ïhOÝãV`}]£Nÿ~#7N=­_WÃócÝ£xŸ¬ZÌÛ<]c¶ì½Øý‡âGeúœ•'Ó«V…Õ¯êÕ?œÔ…ס—ñ^äNâƒGO]ŽÏŽ‘âîøgÕÓûuÜ0ýÝ¿#/÷¸r±ãÇž~!úÂ…ËpémŸdÏuÎþTgëÓºˆƒüWè§ïÍ&ÿò’ÄÏœ~×òüð§Mº~ª¶diú¸µnüýWûìƒo¡.ã|·þŒÜ1vÍQì[ž3ùÐy>5«“Z|có°Py?±ãâÔ  Gï×òôówðæâÇìû±/LLjxWsR!ªÒ#9>r¹ ñÁÀvŠ?ŒÄm{÷pjù„!P„DE2zïÈ&ôi¢P$.#7ý“[ ìñÓ³íȃ§¹x‹¶žnì‘æݱ_Á¸»|¶wr.ŽW~sßY“%úOŠvÓÇ4Qô‚<Ë÷ádhHÜ<}ð§Æª1Ó‡„Å÷}{Ý}8õr¤u?|F¶ > aQO^‰aP¦gyT¬¾zÆ«íQƒ‚ùëñŽª¨i Ñ0+t„»Îô—ÓÄ4v\¿Ñ¦,}¾'& m ø2™ÖWt®gV#9`ú&µéË“\ëã7rû®/vyáN›¹ùpäJ†;TˆŽ¶`4¾»c€ƒ×Šëäû¹(—B©Ÿ-E›×‹±"áꙜ % ‚^壤oÖD>´ÝøñÓ»ºCËM_/#/œF˜¿ÕÃõ =½Ú¡Èa4ÿkúœ rZéïÅø€€*+Ü ¼ŽYƒ^2¥hÔH¹‡D—”«‹úräuÕÁº6ûë_GËë‡ã(§ÝÚwØÎæs‡ ðÃÑš ÿ)Á3EÄðnîZè¶Mkãó"µ8ŸõW|k^;v}î1Õúvš“.„íç†Mö?ˆí虲aŽn¶Je%²Þ‰uRº\9¥ Œ™Õ©hÓy'îõ¼iÆ»“M-Ñ'K)$ðe· ºµ Èg¨<vñe¦ÄàF‰cŽ‰Åâ*á£ÏGácwÄiøE^9L4ÞG» ßo¸=3‚H!%'q½Sœ„žÍñá@;Ên;€®±WEÌ·¸1½×3§dE\ýÜ“åL<^q°Å0å©ñLé?—£[kaå<Žòóí]¡Æ+úù=-„=ëòf›ZîKôùïóJ'¨¥1I'f×Ñþ¼Pú0é|ìd);IíŒn}–¾ê#e€NNÒêÙéË;Åü_—®ƒG¨`À Ðo’õ=‡ô1$«b1سJåù²U)ËÄ£}ø‡TAì’žQò|¾‘ßzÆ#/åË—´ÆÂøëoŒçþ'ÌFÑçdùQʇø8fç9œå%%†d&2Á¨9#ƒÂŒŸo¥EkPa¥Pm±R8‚<RŠ”I»b4CC˜òU UiAÆàQQ;Ÿö´»‹!Y«»”Õ™fj££B!Á´ŽÅ-ŽÀ¦°Aȱ¬a¦HSjÈš¡#9H¥¬VÁ•”Õ"4#7Ñ^›dÓ´ï‚aX,™ˆdX¤‚éú´·‹¦¡‡#ÁÉ#ohµW}uRŽ#7§XŸ×ú¯u½ò}?/áλ6ÎÂPP[ÿ§w]ZOÜCOþâêœM¨H_鶼`ˆ#9·Ë#9Öfvç¯b¤,;Œ.EÚL‡¢E(ïOû¾;ÿcÜþ?Ý?rÑ FÀçáÄò…E4­¢cR"GGAP#5˜»hZMê d)TI‘²Õ¨,M±¦Ù…¤’© ÿÚM¡°w‹~=?—äžßßí^¼•ß6/—+Ö†½iôOŽ½“ê8`ÈßÛ¯*áœsx¸k§a¶ÝRÊsÊÝ•ÙŸ.û<ݯþJì§/²ºµ~ݾ­‚^AçU³ôþ>p/CÛÏÏ˯Ö;à›ÄñNÏÕüo}¹Ùóaøå#ü<Ð"à!«VÇ}·çõé1‹ñ{<í;-±f×–Ù‡É=±Ð8yÀäÛ¤j#7xñZ.(ÃGg‰¡± ’$ƒŸS¾²ìlîžï‡ñüWëÛ·V¿gˆ£-BUå-¼qäp  ÕTÛðñp´êõóŠcöÂÎú:ò‡N ÂuþÚ»û\Ž.s™îWIÍ`ahaÙ×Ót9—^4#9›·S¾àÞï¿«g—oñ·g&»¹ §Ü‰¿+?lþý=óÉdÂþؾзùÂ? ;X#9ªŸPB³¤(z·ýAÁšp?¦)á./ðzúmŒMµäb·;Ö¡Š® *ÚQjק|—ÒĨֈheƒÂ#9³Ý-j²ÉY‚–()Ãf¹³m¶!¸láµB ·ß#76öc‰„áQ7¸+F'h4¡ qMˆ4¯»Î\Ë¥AU$’̪ªÖö(ú ‘–à- ¤¥‰(Xž~ÂB>â‡Óüç!Èú¥ù|ËÊ5ÈCåõœ¼]#9•-Ós˜ù·"&ÂI$#9Oä¢Æ…Pª»Ã´÷°múFÉH<9Q"#=~ ÒñÎ@t%CL©QH2t50î¨rDVbä¿#9˜ªïsÉ&Ñ!/p§NÍš¾ääŽ/\Ì»3æDþ®¾¹ßñüj5#’+B#7þØŸ#9Dæ­þiŽ±¦Ú¤ld„q",CQ/èb¶?åeÓy¶‰ytl¨ªB‚YQKÅ‘®·Ïì—òù2øü¶|=c¯ïöxÝ0«‡qÝÃîû¿·OÓ&ƒé[X€ #‹c=zâÃÔ™"+˜æQeû(­¿A1²aˆÁÐá#ipjLo#‘ 0Õ-³#7ÍT)8#9æX "Ôùé¦=e÷QVƈSƒ#JR0Îi§IpE30ËB«¹j412ŠÔX]Æk¥¥æ^ÜŒMu–åCÝ7ˆÌy#9‹FC•˜–6ËZ@öíMŸa##7i¨Ö¬"}‹S"%›·8Æ*°c‘“³]Ÿ(æ-n9ˆ:£UhoM¾ÃZerÌ­”µŽ–DÈu²¸Ù¤DQ63#9ÑÊÀÃD#M£aË(gxmbÑØÍ©¬Eé#7Ðá1¶“­¡×l°lÔ݃0!h¶eÛJ˜£(ÿãÿm¦ì}0ÌsJêm¶Ómæ ²#7³Åà w$ºj´3,!Å$Cas(8ðÅÊ&Cœà‘Ò§“|ýÆ~\r~ßã"½A‰§ƒðûîÝÍÌø¸Cpï½uxÇÛ¹¦¤‚,ªèòÐ<(!Â#/‡‹1¦È&^së³ë2›˜pÃúÍzƒP®bïíçAÍ4#/Ãìá>C²ìtÎiéã¨fièö}GÆ:gžÝ\Úýt§H'X)ØŽ Fg¨p{‹‹•Š$–AbŒX°´ª©øÖʪ `ÓŒÕw†=øeŒÖ‘¹"æã Ë‹J1¤J>ÉðÐ`ªÉ.HŽ)FD‰©…ã~Û¦Zä…<`¼q‘–`_¿z3¡²OVï3½Œ[P6qzM7§B‡v<„W¹âôi±³@KE.–ˆ4Ní ÔÈ a#®ÓŒÅâ몭B!S§/íü²r×k»¤kmó…2ËPZ^å½®Š8†Cójáýïyý}wíõòÏ—|‡Ÿ]ñuie«¸dŸ.#×ýž(Ó²Œ`Š‡—”0n€äV(c§ÓnÏ®J.ZVƒ#qn¢1ÑÚ@ùíp™s,d)"ÀPF#9ýµFPÒ#7P(±ƒ¹TÆç 0U0$h}¤u·}j£);Bº.¬ƒú²–‘¸£ÁÚ9ĤiØòªŠF ¬jØ´Õ#G·žLî!LÊÓDº Úk:öÌâ(7ߘ-œÖs+XpJ1•ØP„E“XJeI.¤kL[ñ¥bÀ#Q#)_*rÚ®ÈuT4‹I¼‹õ²¹ºTј5Á-ŽÕFHq,7x÷Ám.üQrë$™#9:H8i 9Àê7W€ôÓ´±p¡¸hˬ†lcpÜHˆ¯fƒF¡§ëLpñÀÃN3R3õB¶ŽÆð:.°«§0+r¸¬#7”#ȤË$c­VC!*“v¶­À+ÙßkP·b{£†Ì1¼Lf&h'ç`Ÿ~:@i˧¥Ôm?Ú"v«Ös5‡MòƘþœË>Û¡~x—êõ#—ÀÎF£#7Å:÷‡¤™íÒƒ6C`Ð>âʯ Íáh0sgTïhv-ª¨VûÈÖÅ!'dî¶4ÛxU÷Ú`ÊbÀ9roC³|¼`/#9«!Ñ¢-´‹%×,c$“V/•Ü–ãU×>–m¶1Â(»†ó¿;èÍK#ÞY$W³Å×á£3lcâÆÕh“™ÎÍÃxC"mh1•É9:zÀÞ—he¼š7‰š5íäÛƲÂÆúòœßlé`A»Ð¸ÍYÐåãK‘*.q̺JAbÅ>u`ç5W¶¬ÍíË[mýZV¿3ôLЛV‚‚gaí1fáÍÆè8|K"ŸsmŒÓ™¶¡0ÚÀìé6ÎÆâ0¶×&Ãu˜Bb““b8;OÄA—f„á—`ÁP`¾#â<¬JŽðqÆÞRà&IaçxÛ%Õ½õglŒá¶`ÜöpòÌA£ncTaÃF472n}Èãa™#9rú’7˜fð–ï[”/^»íy7hÇXÖ·}^BÞD݈&Ç}¼—`ÙnoËá ¨Œ\^vª»É•P\Î{báif¥jUóœôÓ@Sº¹Üí¦8\Aƒ%¾ü˜g̙̈!ÜÚ9—„Êå(·‹|âÙ7#7­t®‰¢>’N\5¸ÒÜ#9#»ÁGV]WÁk¾"ùÚwT%ÜQ¶ÔvtwD“y‰d¬w#9Î6#99¼·c\&ã2Š]qq¬û¨5‹#7ÙŒHm¶÷:1ìºEjÇhDèÅ7]]g2rgfÊ™CKW#X†cƆj}áá6¢µE“†7Ea’3„ç&5¡SeÈÍõrIÎÙ E!-Þä­×l #9Ó¨cÇ.Ûl–NZA<“kRhA†ÓÌØæ2û=Ç+ß ÓyO¿LêØ66í(Mö_)ðŒ ÝÐÐ!(dwç¯Ú|mÝ1I”O*m££•i*x‡T9‡z/8òÅwWÂ^ŸNe±ÀÔì,óG"qF"è÷¢1Œ!ˆÉUùâ•5[mÐÒWþ»Œ‰8œí3Ê"ë§óÑ;²~攘ç¾™§ì*„ôïýWËmˆºunLLÌ8òÉÞÿÕuÂèâˆÂÎ\¥$í}”¨Ì:…8žÂOKCé'e§fˆ"&tUN—Ž³',7M·ü=¬àÞOÒgâô-´šKyÀh§¥N2ƒ‰õÍ\¢ 8Ð#ÑRßj‰ÁàDýÞâѹFìœuw¾Šáé[[ã>šð ø2Ý䀹Ðißè”Æ´’ð$Ë¡pCÌ¡áÉ¥®Dîê’Iñ^Õ9‚yÐq’ù†hÈ]t1†"ÛFY·×ðè>6ç”ûñýëãË*ø¶µ2g‰lœ¡bÛ#/Ф¸#ÀRže–:»ôþ{?ÑÙÂìÓ NÈ牢 àžNWÁîÜø€/Û|äÇÓ—6CþñíÍÌþ{ãc†³¢àk#7wiIø.á& ‰?¬úÉþ»íSYðƬðw9*=Ád‹*?¨Ñ½<†š#7F}aËÞè‹d#9ñÎÀ;?@Qƒ­MÈSTu‡FâqAØ&&÷…Ó÷¼Ðwsà/#7¼.ŸˆýÐD|òEÊÉ´àøÔÔ ÄÛ0L61W@;!JU#Þ~:ÌýOèþéhÊvs—wú3ç -èpÈ—¢¦Š%à2_Àãɘª|¦7GÓ(~Ç<#7‘JJÙ,»Ë—!B#96˜%Xa-¯4¸ ˜ÃXE_S]qŠ?O)W E#7ƒÞ¾yãóË Â9ªŠ·‘Õœwm’˜—#9‡39Y)(ÁÌ#/ýÝ1«3\H’*cdþ#7ŠÝVŠ¡Ý¦¯Â‹@˜V¬´ÐD2l©dè—÷ÅB|Û#9|´xÜÅy|#£6¿åxÕð¢¤ò­TôumŸB—uú‰=L:otß¾Ó:#¤ð©b'2™Z‘L™‡@j¦ß¢Av¾zb$)¥j"¼]Jª`Îq%[Ž“¡î2»¨ƒïô…îÆQ92eæ#9’„Ù̩µ†í6ø}×-´óàÎõ‡Ç»–QÔ|gWÝ;ɯp=2ROiÒ÷ ³a9œ"Dôc¾h>Î5¡=H^Õ#9E€bèhC>ÛšÞ}+·IÎÏáfíM$Ö‘OfÞâ7b‡Åþñm=㬘âË»•ê<ŠniåØf¥#`ö¨®•ê›MdŸâ§®BB¦|DŠJg­ÙvÕ{NüöÃÙÒM·ÞŸ š<1JÇŽõÆÇÎoê—˧“®ƒŽvB†Cní}Ji“ƒDˆZ-Ý @d¹­1øñÞ÷T0Œ-C`fW0¡`БéÐv9DàŒ£…#/Ÿà¸#7Ìžø2e»N±|¨çw#7ÝØbÛœ5ng53«T¬æî–ÆueXa„zm‡>¸© L:- !ûµÁ‹"#Ž¼ü8#7{éúôÑÑbÄQ&–OÍnÙ¶8ÿr2¦rØ>ÍßÂôÄfBÂeâ-3ÍJ¼#7{R{¬²ê¡gh§—­žF¥ˆT©]R÷¢çäÇ=¢@Ö4Ý ®¹3 "äx`71–TJ#9ðM›ž;àâ3"èœJ¡Ñ ÜD(]uG»n¯å¹5yž#0¼˜¿Æù|#Ë›‹<ߊ°àíÕ; uEÛ»` 'ÎP‡°ÓVánL(€$ı#ä²Õ’c0$J‰ò<íL-Ó½L×·&”Ä\ËRæ‘òãêÜGƒ“—êz»y&ÂESÀ­dJ¸U,•>¼<Ö"ý,÷3QúŠÿá6nêN‰tL\ èªžm@£ïŠÁF<ÞE#9n~¹ÌmÀàÕ©°øuša¡çcˆ¾ìçžh¨=|?|$i¤ÑEdD„Ô$ý1¬s{)4Γ#/‘7%D%FAÚa ¤9[ô⠘Šç,Ó?ÐW8“êåàd¹Ý!,Ú(-|€;xÒn“,%ÀÜP Âv½E´-=e"x­šÛ×ÃÆÑ(ûˈë´;Í-!‹^b{‚sƒÞ8œbùÕ"µâFÍ»úì²éNw*hPØáÎt!'áæYCÆÞ6‘œVÑ®4]¾ì1ãn-Rg·>7t‘¹uíΛ&^…ëÍȳP;ñÃÑE ö»>huZ·†IÄ~5—½Ž¶ßÎŒuxÙºΖðÀýšÎ“Q7s¾¿7⛪àáÎd„#9QÐÝ4·¹°ï˜Ó»…‹Z½ ¿Mšx8|ÈÿdÒ)Ì^0Ÿo¾û||£=ûQÝÊt–Ú÷½®;”fò^²©Êvç,G¥Üçïôß…Fûz7ómmÐHæ™ù·9Þ ÅŠ-íš$¢xxOΑï*MF¢Ðð¢9„¼ìÌ`,m:TiÛðiHòAMü+™®ƒl#«bÏ?†æ#9åzYÇ»ïET`Ù¾Ñä«u#›N'æP¾:±¶¡CŸz1™aòZnpg}›ž½ó®žÓø>pE0§h¨©„ˆì‹½¶ódSŠä‡—ðœ+›,3ÏBÏÓ¦óúI{ýËÔ#c‚6ÅÌ EyNÂàJœ¨ÊA`Ò£"¥Ä»R) -Eú¥Œ¢%yyú¶wÌÈšY<;ö‘áÎg,[Xi²Éü&|3MáU£Ã]æ™u»Þ@¡òE(‚:åeX¤wD³#KmÍícFQ "1)­áMþ?LC&7(eò–gYeÕµöÜ°dQê;Æ5]~%¶è}ÃõlC¯ƒy ¡¯°]]C»ár‡Ø€Ë˜°¨u™2çÇ,Ü€DUËÂÍsY±-ylÎ(÷&{éÜH>;Þb¯o‘Œí»Á|èÛ8ÞéPø7S L ·ñÕáƒÒ •î{ˆy=18ôN,¦sÇ¿´“€\G~$BM :<e-O†°Z–#4mq-MŸÐ§ïÚ>8:o&?t¸­ÿàUùkƒƒÞ¡Ü¡GàQDy¿9³ëµiªÌuãm#/âTjWŽÇþñ*B#ÒÓ\nÕe+òÒ±.Vk•m)c¾ÅkagY­b5,#7ó{K7[êhJÜ8ʸ>ÍÑ €ˆ!…Rõ£i¸ @Š¨Xïxºoç[YÜÚmª#78UÔ/sµ£7æ^*$µ»’rz¬žOl¶b,ÈpQ#9µ]†/lµà<»Db#7(-i¼\ÙrÉ¢«“ ‹E!E‰û^ŽŽØàìŸ#9e!O,u¯äF©ócÁõ  £â÷É'nàÚ#ŠÏ…aÍŽÁÓ˜{ð·%N讜p²0“p8žXf¬.ªÆ.+…ú¬±b§ŸeŽ¿E’¶nP´–+ Y–M6Íw?;ƒKô®™Úöƺ¸gÅú«ÁµRÆ Å%w':ŽDV-æå˜L-—¾©¨]ýVlºßÂ"ü±œŸ¼÷Î:Ò*xÔyXþÏ:Áèr]ÚjÛtë‹Þã"V›‹tº )~pÙ­vÊRró¶œvÅÑÛ,(Là¶âÅàç«?¿:ãV˜,Wƒ!?Á`É‹#9à³­$Ä*¿®½óÁr^(é¨g·0Ÿ·²#¢=°Ý2údóµÒNõ!o~_±õ}.WIé¤nÖXmxÛ®fiYÝ瑪äƒï6]«s4u,sÁylü1„4pº"oFN½(ëRð¼‡ß—æ h¥&²v]‡Þ6ÆÐÛýÖW2oK9ÉTÐÛÀûù>«2xõùttØÉA²?WFï€c”Eþ)Zíó/ÙŸ“¾CYÞb#7õ[®L¶‡¼p'8JÞ¾í·³ju³¾´Î±{ÌËw÷q=üs¼ç¹©-]4#9+Q±Ò:™2ƒÐò37>æóÚ¶¥ª,‹Ü8¨ê¬ؼ^¾'‡WªÇcŸ•uIõ"Š1ž$$ù—%±îÅV>X†möZ4ƒÃJ’‡Vš ï¢;#9Cå·sádmZû¬6^Õ¯Ç06SÛ­åÎ*™4úóŠÝMÙBʇl—}%thÈ'UV7U€Òo)ª<¤`ðn}—=æÂ÷#9Û£øÓ}^Dê¸,´tÍÀºYÒÒ×àèóAÂ`¡ êr¹ƒ2w\ùë]A|Š%BVëç]ºZî€/ªït¿cÁ¥Ì8ñ+èÒ¥•kŒ­†=n•^-sMí»MÂPËc›EVÕe½ÏrÝW¶ Ы™eFè3åw¢Ës`w#7/”ö| Ú9Û¬Æ`ÝåmÏ'>Õõ#b§F5Lv헌ݠÝT¢¬øé6O~–‰êÆ–*õ?áÅR¨R<„L¦šN•¶½ó6–®ï¨Û»öc_l™ÚuÍÍ¿Å`´Å£œŸ'Í,Û¢"[XdóœMu„= Ç6¨®‹2±íª9<¥­ž”xHž' E_7oÊ7+3­Óo9g`ÀT8;:°•’¶#/\Ý1}s› IñZŠº">±M†BW¡I ›ÈáZ™[Bîw]Jìp|–JV²sÝ:úŒãRñ…¤q¹n›"ó›EˤZ‚@Ä4ÎzoÖ&Õ²šØpt´wçs¥¸jt ÖN—lºº\µsÝ0ÒÂ(±†¤ËU«… ˆ£ËjÛ=g8«"]üq´3|“C 4ýsçÇc`†Ši³ósØM)"$Âdrƒ½Ï“ËùEô‹=¿Sç³¥Ÿš×£É2Q(G!mðÕkgŽºAÜ2­¯ˆ[ V°, m¦o{›{š×ò›¹!º Òè½÷í¹öBó>3Õ°tßÚT3–lå âMi)æéðY,ƒ>èÑ7ge£}-Ù[#†œÝ{Ü¥Í榺ÊÞ¶~kê¼½5ê£:·~Uämòïbí!š‚»ÚÌã²bt„c(ºÅ¼×›ôÓ#dÕb±ÛØ8îÔægÒvÏ6L¼yÔ™:|q&¬æ1Ööã+TkôRwÙ¡çn¸r–#7\q!íæûÞ9ñQaÚu^ÕSÇä÷{¢m×ëõóóQ¦+sxöêJ¦àå3º8#9cÕ)ÚÒ&Îì-bÆ æÖuimU–U!’”fCÖW%DsS™Â’Ò7÷/¾ìÆ-”A9°ãõ梩uýÝb¨wT¦D7·i‚§¢V–±—Iº¯H[ÙX’|ÊvÃ[Ü%`ÛIEØFœ¤qxp#ÃÌ´"‘Ö fŽàEö¹ BŽfH9S»â»jÚUõ‡:§3ùâãÃÀ“…}3‡èYyÓáeo3uG¹êtø½ŽÇÃøïïÞzk{̹\dï ×íµ,äÑÆ{>k×&úôÇQ];Íïí·_‹ŽÞ¾±©38z†iGïw ݼ´ÞÎ%y™ëÌ̦ðàåf¼p/ô\uŸ&Æ”úøà:ôÔg´« E6\-|åe'¼e!; ÂÛÝMÏU6FZ¯5q‹ú¡ú<¡l?ŽO%Þžµžø7ÅbÏ5#¦ ‰†Þ"JÖö³í¬6}(°Ñíð|*ã¼j¥úÅ¥ê&”ªÞ×E…¼)³Ÿ»‘ÿG¿±ërcŽ³¢l:Ù./É͇]!K£ªÅb¨NÈ#7.ÁR[cŸ©²þˆ5ïË•æ(H\‰7°Q©1Q¢¢ÑWÌÃiÝÎo¦MîaXiûIàdñŶ^Sq÷'`c·åp1Î3Œ —£ûuj“;gRÔ”Fͱs})¤4‘Ë ,E4¹œ…Ï|匱jUL$°äÝN°RcÂv¹.‚¼rŠÛ‹ÃôõµgSã”DM¤bå#9w4½X”ÞÂ#°¸wà ×CO6\ùÅ „°tì+~ÕŒï¹TtôÃæ"—ŒÅ†øEŽÏ4#9Q#/Û5t\]‹öÉÅ”…8Åšäqo4Ÿ1l­\0ÔæN½ö:W•ÐNê#/xŽÒ4žsÁ¬¾Ë:£°€àBJ(fîî­ù7FµÃt¯yjHLVÖš³ù_aî 2 7¹uXòØà"ú=rÇv…Óðšloós`ÕKJ%á‡h#/€ã årÅF´“úš¥â=*mc·yíqU)îýyî+N}¾ÃÉâvÃLó÷,çþO8ÔCëÜ¢}m]y™Ò¤eþõûïÛ/ã—œ@µÞ7"U™4çoÎWdUÕx9ÌŽš†˜Î‘!×Õ±ám_€£ƒÁicƒœñ‘ÖõÓÆJ6Ê}ÓZMMU¿šë6ü›=£ÉüwÇ9èþ+ÐM¾Ÿ®fq£JmÊ7˜!ÌÑÈQ %bF¡´MÂê½mJV)5[ó[#AGOn¬æÂãhÒfHFgi¾?üŽÜä>›ßWV`Ûñ¤9ïZ£¢i«W#ø+ë7¬MÛµÃÑŠíW¹åMéñÑ·FÙ e·GÏy®“E£FBfFyëUÇ­áÝ#9iœMçsÁá®'¾Æ)›ߪH\Û#/(è¦Â°ë¾{ö AÆ·a~¥Æ)³CÖ:\ñLÔ]9½Ë£NV芛\Xº5%ã“=¢âŸF‰Ü·(\dÂ#ÎúÆP$‘¾_•Ÿ…ŸIŠþøþ¯ŒrMº¿o(#9ñûâo9›–òh3}ægÚð¾æ¶ÇŸ›®Éˆ´:J—˜0šýÞÙŸ¼çh¼T’|QÌyÀou Û¡×űïxG™lÔz;_Ï“¿<ÝMŸNJƒtn¬ú|ñÄ÷ ŦùÁ:í^]ïÛÕèÕ(s[E®ÉÏ„Ô¤‰o?=v÷ác0éÁ×»w”r9ð>·G:íën’<$=¹Õ@–ª‡JPŸ«ü'³VðÇ‚aÓmB{1ü-j›"^ç(F„ðvoú<ô¿IŽ`ú-F‹)S8»|Îwá¡ÉnÂÇ þ9 Ç$a˜hÍ€5ó¬UåçÜsÙÖ¶º¦Fywµ]#9Ç97”ùx-§uL>û‡™,ÇQeÓ¤J7ërý*â J—£×—àŠ’GË—Õý7Ç^WÙóŸîêW— n‚ïÌ}Î9ߦ¡NáO®öÖ1KL‡j‡W6*÷¹­Ò'¾~£ƒFávØ2eæOf§lWJjd±¤Uì2+R2V ‘Mø?R9¡—FëQ3@Óáß>'w`¤:„2ðÇ0c¯2áæÕ¯.ñ±GŽÓ½W•>]S:n&„#/V!zêÄ[Â#7ë …k½h7nÚô\ðý|º¶ßz¯#7¹av¦ž¥AD'aкJ#7dj/dRÓµ®#_Åàùr/`ÙùCÁÒae´uÒßH@h#/yag¡TÑS®¡¤’Ñn[¦÷¦ßF6#7zr? °|y}GáÈZneižŠà…!nÿ–÷U=½nâ¶4‡ù/þJŠµNÛ/žáÖºc%R:­ñ3´)>íiÛJŽµL9Çô¬#9@îZ%€¡š‹ jv‹^?VGÚ{ïE¦å²Š ü_±Üü×ÈñË©36y=}ðöØüT-š Êè2QÎíªoŸž8ýçã~ÊÓ¤§0-á¤|®‰¥ZHg§?3ÇøOŽ×&V¨ân–#7£Í-ͤh—‰µ*ûƒ¤Â“†‡G×±$È~¾ÊÔŸNBeãnõ¸Fu%ÍI$jý~‡r/˜iÌËݧ„Ð@xŠý¸gP=þ|nü»Ç‚x¢·—¯õÏ–Rµ|4aÈBŽR”DæHªR £ÜŽa¥èñó/¬ G1¹?/¤9„t„ÜPgM6Cæ#9Seò=GnŽ¨×{ã‹ ñs¹#9p AäÇà×…úÅ”åŸÆiùþEr*"üjû~9ÕÈf•×ÀïùÓ–b»vç÷íþGaûã0&Ã2¤´ƒc_º[ì6WêôX”‹DBÄ´Ò)H†œãÓoC÷}ýÇaœÛ/Jû¢¨ð˜}ÆhX‡îçAÔ|JÿoÕgš,cÖfk8gž¹ßÓ&ùóÛy?½òeе~ƒ\¹yÎä<*ª(&˜À;ÄÜ]ªvYî/[®µ'£ „‡iÄþ‘ÒalîÈtÆgØÌyÓµgÎêì´Zy£#û©†ÍƒèðBW.¡ÏÞϳ}Š,?AÚ°o'”#î#9(.@Ÿ-ðvâ‡è®/Íýw‚sfÑᨣ0åšÓšôþW÷)Nd•AÖfBUQnÁ7þª‹<øâQA±ÊÞÄ@£6…°¿àVõ÷×ø‚ò×O‹*Hœ“’Ê=D-òògv°ík夙 õñX±–.E‚ôb Žý[Ç+õèàºí¬>p·pFzò#7§ø0·ñô2}ßH6:)鱸:Øè©bK»¡)±v´‡6æõ`‘p‰Fs0õô0¤|P˜sýQœçÔ&—N>»vˆ—‹(ô6© ¾SÞÏ908’'ìýÑÁucûTCH:—v±¶ÅÉlÈúîˆk“©ÐCÖõ4Ÿß¿/{í?~¢D¥Å6­V*UY—¼âàAmâîú×î×îüIW3Áq*Ѓ{û/¼j!²ÊÝ/À§bõ¡P”[6£«Sœ_#7Á‚ÿCK£µÛ$¹ð€èWVyìpŠ-8{ÑOF÷`Ptëç«,kf8»µÀv"€|PÒÙ€ÏìÓ”H—~½=1à³'Î ¤ZÓ'qÃñî™CYœAÃÜi”Áiµ­L· ü(&IbÕ1–œXX›LO˜Îqá­±¶bC,ÇA3#7Êf<±)ßî>ãŒÏTV=ïö_Eç3b€ ˜C½w0çY¨YÛ Nº/l_«Výwkª6„Pòt5gÝ–2&ü³ÒPËÊ, @ùqáÅð÷ã ï÷õ°%#/¶Qw'[ùÀ ³!•º8õ_åwL°YÙîÄìÍg=ÿ;Pñ$™fÈt{?šµ קÉSâ‘'¯Nzâf°Œ4>~"Õ9HѺ±µ,ˆF"%ÃvèÝ(°\Š0¹ï³Æô?¢ÄÂC`(-3¿ËåûÇM£ÐÍ÷ q¯¨Æ4|Lú\Õ7HqHl’#9¡6:ÕQDQzÛG0RŒÏ£ùÀñqßµÂîœS—̪~¶Î}ºYõý“M#/ïd-.WTð1êDMزëç¸*¡ F:"ÁÍÃ¥žÛX€=6hñ~ž^:;‰Œ#Ï)S‰8¨àSÙà©|è;ÈÏþ,ë ¼åôâû#7ÍÔþ:·Ü7¿Ýü•aÖNQż¿y˃2}}#9o#7GÍäNýWIåæþãæwƒ¦/³9 "ój€Ä¥Í7Ž1t–5Œƒ.fÉ]S¢h—IÔ|Go_€ÎÁ¨;$ï¿™å‹bÏßGlgÝ!MÙmó= ] ˜Uåäéadmä#9u#7xÌX“óÝd.g”©|›™R˜#7 ½" n [!-l)‚a7züJ®X'?׬ÞnE“?„ …"©ipûÝÐxò×iÊë„òZÓ“ƒîTÆií’Ï(⤂Þ<Õ]1"Ñߎ’' ¥íl™…ª”D»óE«³·_˜Sžîƒ(~„„¬-r!e½Üg=0^2VÉOMô¾*ãcåˆnG½»cçÈÝI—5ÈÁqäwgl „õ”H²opxEý+Ù7G³lÙü­ *ý¥5‚W”A«#7á]sÜ‚ˆ;`œ§Åu8 sqB@$¼te–é`#È´XýÜÞÍóƒ~:†Rª2ÍРCàÈQ׶”z‰A–óKl„!…/†Êi X :6î[šò;¦óú, „a•KË‘Ý”_eåGºÎÈnØ<ïó›ÜR£Ö<×–ýÉ~[÷ƃ2Úáøù܈J‹…ã—" Q}Ù…È’Zäµ×ò‹ØAáûðà¼ÓÛÕﲡýnÄS‹ß†Ÿ–X›ŠJKDHKù‘]Ü°¼S먦¥èæA;Ö6ãÛÁÛF`uÓå‰#7*XìíTî&Û>Ú“H´ÍoQŠÏË`·ê;ñÊ÷³ ‹ÓCH1˜ÒŒ‰rT…ŒðggL@àˆá2öMƒ8íúÍ€í¬a®îUÍú.Rªá–q`¢7%‚¼!*ÁÄ828âyBàqÖ8vpºÆj›yùÀ™[W—äÜ€mß1>s?Ñe㾚–8é¯:K·´q`\ÀÛ%$‹d¡æÞУš¹Ÿ"ˆ1Þªè¯g/±Œ`é'xÖ ©žnâðˆHTz•DÜ{Â}l™Ýg†ÅÛ#9T>=ÕÑãà?™ò¾=zú’ô\×™-ænnëJ†A–B ŒˆÐ«ÊáÀlÐ¥ òý7ã`„Ow¶£)êäe›Ni‘vÇëÖpaÑ€[…hó§‡T5aÙëÆ; ÷mNÉë1áÚ_™fGÓ?hô­í‹¦Ú?T¼%ʨ»Vãè;Æ.0åß6Ò°»L6¥Ï^Ü\UU~~aDÙbëyÄ8é'È.EÝ›8pŒò}£l4Ç•'Ç€Ö^KdJgÏo)ìð_Ur؈j—v”Þ±0Âot“vùRO›j“¥AoG6-ò7õ¸8ÓJ¶ æp%³{-§u0·HmÈs°O€Ô\&ÌÆ“6]¬2¼Ìnši²ÙF(MÛbúÿrDd )$^ˆçQ:Ò².¦3˜ºPA\ò•}`Q¶”ÿðd¾ $ù#79ð{&Íkœâš¿¦‚|Póññ‰b6,âDBÕË9¢#9êÞ§.Øõê†ï#¦ƒß‘™}Öñ;;é³0&w{ön2¬]Í1ØUß"A´åv&L’2Ò‹I¦ÆÚtí×åÄtç)†¬ëÈß™¶â-=¸ /’ûÅ&é©Ç†;9ϧVñ&dvC®ù¥&%=„LÕ®¢ l%ÐÉCPö|ۘב„?œ…s#ëxhM\~v»uÆþIÝkõ÷çž·|UŸõÏß*\C½g£ˆŸM„Õ&ŸÇþ—›ñ7|ñ:æ£h.³”D1¡ ‘Ç1úbÇ­k44~ØÃP¤’PÕ÷~¾¾…Ú¥R¥8¨#/—êÚny‹›™WîƒùÒ·»ü1UTæÀM¾ƒï"jýŸi²:üh*¿ÊçÇxî#!þŸ¿š)=‚z¾¿ëîݧÌ?ÃÈ0ŸR}|/>ü±QU`CñAÝ¡ ÜH»·öå•Å÷Oö>ÏÁ>l#/˜ø#/ø½^Æxæ õ2¦ uJ\eñ#/“àÖ¨Yß Þ©yIwo¶{ùˆ×:¹ËÍK®p#9RÑžíM˜b±…B}[Yä„9ã&;(ÉâÊ@‚SW Eä¢9'fÌzRhR©”ÒA+ÕVÌ¿P‰‡ðý<Û1%C¤Ië÷ùgqËÜkEõõXrº'P½¨øFúTÑÓwz¢›f#[5R°ÈŒbY·™1Ž \KLùÓÊ?Tª+Šj½T/x`È,Ì#7:]ÌMÉíÚC —¤øwZ÷…ê\õ°Á“ƒIiB®¼l˜˜öÉAÊBõ›w¾Æ¾2”zÑèµ²ÿSÝ€#aÀ¸å}0RøÜ:ò<Ý~oÙ´|Iu£p4r·J¢„·ÓŠ–)DyBÛìpM¨H™È7fY'0Q0ô.°~YŸ¿øÿK´ÏŸî¹¡Ë׫{ýð-#/‚:Ã0#90À£ Æs‚¤¿?Éà!õ¨Pû²`Y•ª®òAhB'/AADñ°#Å1ú¸¿±ð#9`ÓŠøËä̈mÈr¹£Ì1#/âiˆ¼¤5îˆ5H¦‘ö»KÓ”£[&ð°#/d3´ q^ÈÐ2õv@øø‰°*i”@“µÒ:ùçé…tͦ&Ž)Bl=ŒG’ŽÎú6@”…&&n#7Œ'ë᡹Ü7Fð¡ÑÙ:&»Eî–É®DÂQ’‹hb©×m¤8”ý‡$E8 p ÷hˆ*gµ#9Æ}G¤~Õ‡éTÿ×îöoÄ{#9WV@5Œ EU.,郙١ø*ø×Ñ1@¡Э,a0¡ÈÀûˆ?A•#½W+&!Rg¶Í̆‚r#9BpeO„@O*øMáǪþ·õB'qPwr•»M™‰¨Êínqu “»ø¢ŠsëCíå¬b³¨ïHJïPSïuOh<ÿG60,¾²JÓ[‘ý|3M†cnh?½ÖÝ+Ÿ2GG&ôÓ÷Ðîä¢0ñ$›ŒÁhP½QŒŠ['m’ï9h)Œ¡Ï žÛh‰öòá¥ár%32•åA4°Œ£‚¥Î®Îd7ÔK÷†È¼Ç;÷ߘvD9%ee_Õ%\/j0ïšìu†Ö{%gGê–qQÀ\Õ¡PxÎMŒº(Ë#9Ü‚:JpÅÃ!Äìõa dd‘pô?XåÕCƒ'z3Tj¡”=Où8ôª|šbÃQtAäòƒ«v~‡¤Ã`î؆…oŽÊš+«ï—˜S±D_9'~ej}"°K«‹|ñ<…Ÿå¡œú1ˆ•žŸOS¼X™3áF ×»`M¹Ή➈ù5£"qIb™ óÇN#/:lCB&Õ:Ô&ªÃ0É$Q¨V Ž‚^ùtH›KT‹ ’¡’!#9@ÉKÍ—ëL .ó™w­<[o™K&Œë:)KQåO-ô<§Ð."½:‹:Ô‚t¯¥À¡èÏ×Ç%©öJÇ•N†yO|ÊúìPD4·Œ¦b‡K³6>X­³„(åÛ–°“`fC3H[¹#’Ž-*ÐÒÙ‚=‡nF q!8|ç:Š#9R¨™@°J¢¤Hw^ ëÞè/†t¿rvNÞ wè ¨Å¤))ׇ\™#/FDU†VËËHúh—f:¥Ý.Ì9yOŽJ.",#7eóÈ3×}kS®Ý÷ò¤ÅvrcZM„U<¤x €w‡ŸwË׺7×Ëz“ãß<ì'Ö_‡ Õ# S§>ªß“cX”>uåIiBˤ…A¶#/Yþdøü¹UVu<¼}üH£ÇÀ<7!ÖËã)'kÁ ñúuØ`žIsz8¯Ë·„.É—Щonö¼óAž~Û2ªB¤E¦‹Ô F—ž8XwìoÕ+J îLŽ<;ÜŒ3Ȳøøì½®žˆ¸É =8“¨C©&8wS)Aøž\¶‰¬€u³|¿|ì¿V+‹T'nÇÕ­ôìžýV#9tEMÕ^ y|Q(PUzŒV!TÔeÍuwPg®òn:ìÕwt¤– º™2ñíF§Âú›Þ=¼üÇ]¾ŠGF¥¯Í¨4Á³Ÿ vJLîš]{á³6[½ìÅäû5³r¤NšA|÷vß»XhƒÒJ`Ou¨,ÏLð…Éž È™Ó:!‰H¨¨lõ;h™'tÉÏÜÎéGP';KP¤€Gó Ïfû#ƒËÄ•t0Y·§@–nÍôg}Ÿˆ¶˜*ïf8É7u‘³l¤œ#€ìŸ›c’CôÔáÅÐø`gªåÞA}ÉDØ3rÔñ¾=ýp9²29¦éÐ^㢟Çïõæt91AAÖ#7M˜„ 'ÁÌ46ÞS‡wK8Q3ÂQÜT×÷}ÛúXÖbdú]oﶸÓÄ!Î_•3÷v¹§\B@˜†Âb†—Jw¼y50Ôû?Õ¾Ó¹ºçÂrpôŽ™9sÁ0 ½å€T x!ózvz:zŸ–ε{zºzì~Ư$˜ËÄm4Œ¯y‡ªxYá*ôrÉÎé#r9™dfQyzøv½&fKÆCa‘¤$Œ§®×•âúžv^uqîé‘EC¨d p˜hˇ±òàÏ2MnøoTwÚQ#9ô£&ÉÅtg†‘ýs{C að³Ïåç3ƒ˜ns<1Nþ¼Æçgßm<ÍBå0uCŽþk^ÏoœŒöøÙ:;§‡$Ù²`„³m†šA¦VeÊI­¡&™#/bd`5i"ùœ±@{»\MŒÓÒ‚Ž.Æ0sy¼8Âx2©¥{„=›±>íI9{·9¶úÄNµ°mAK0ÕÙiÚ£%v¹ Ð0‚@ÍXl)ºªõXHv§©t¢@ˆJ+`ï“S³“=0·§8˜ÈâzŒr¢Ž*PP`ª‹ÈÈ¢Î,¢’R ŽõC³†‡„¾¸T:ñô1§ í6k¹ÂNÃ85_:®[ì„^°ã±öÂÞc[—;:~4„0{5ÕmF-“•÷Âo}åº;å-üܧl-{#­3Ü61g3¡·Ž!1À°ÄÛ|#/õ>(-Œgµ–ÝlC§no²…÷ܨQšvW$|˜:†¢ˆPyµ¢¯Ø^!-Å[„XnûÙ÷Ü©È2]¥A4"Òi×&D#JÕÄž†êÙpGù%ybäÑ+À.NœƒÅ‡‘#7'6^žÐ(ØAĈÄ4(ªÐ38J›‰’>*…ZÙh~Ý”1!é§%,¹3¬œ+u˜eµ Ū’ònš#9G#/½½ß‹%wI´T à#/:ÍÎÖ©ÒhzT<,ØYƒzü­`rO‡#4ËŠD¿éç~tvkå’:Áì ô¯¶fIlîg«Z!UHñÃ×M[æ1~zݽ|®›E#7ÂJ ¦/÷m›¬lS¢H Ô[RÂ*´ Ò܇–£wÙˆc `÷¸?z8å²{ ¶d“(>Q©aÐàÙAÁí~Ô*«ºvpLì#7]­ƒ¢³§I‡—õždé·á¶³é´E|üûÑ#aÄÛ‰'õ­º×s+Ñåç¯Îa¬ì”ûžX’3}¼aͦ,âkß^O ö'c×iÈìÞ¯ˆÙï?!;1àÃÍ$(háuÙ&^r˜lI-íÈã-ÓCÂG©!ʉ9´baÕ¡#7d#71írUÔi \’Dí†Q4T>K¯)ª4˜À–™54&¶Äz^Xh½.a¤ÌRû¹ë¹Ó[{<.¡ö›bt$íru2bb ’@¼ÓŒèÍg ÉŒ‚øuüë½ÔYRÖfj|4Sh<9ën·itçèñèäyƒ×@HùT é¡S£ ³nT=P©ÛÍAÉißSÅdDZ{¬æíU?Pí¦Ã'Ú…™ª©ÜÑMEýoŸ^å  m!RÁ¨þE’󢟫™{Yh€œuîÒºD(˜ DåUà5ÛAÑt$QC(|°#/„ò_Ãî|g`TÙ¢!¯•¾L%½Á¼Ž¨t3Ð<'òøgý^òÑÖ)ýS¿„ù9ÁøÙ2‡šOZÈ,†ƒÌhÕŸŽÞ}¹ôé¿œðB퇶QMüíþà*~£g»°wü!ý§Ã šIúDZ³‚‘ Á4}Z‚àÁJÜB¬:ᬦ†„—Ä“#9ßñþù¸lkC÷Øþ8ÿ*}ð$4Ò‡)ér{Õ&z!¡;Îë4Æ=ð$=3žÈJšÕj3‹#9_ÚšAJ=:Ýw͘›m˜êöIáˆ?8O2t hûcÓ™ŠܳS‡h®î££æao2’©Iï}é½®#[Lé;ÓìÜó÷HÙä5õ4Ý‘³q§ 4xRŠ$€"_çö{sþ.{žô{Ø?çܺÞ3÷¿×N‘´™DJoVåÉnO§íÚæ±Â•H™°*#/ …Òù–y\–Üè–Úv3§ó…!¿Z†#9ÓøUÊJºä¡`ìô(õg7Íâ`^ˆAÐØß_íòì?ØÛr¸j«Ž{’#/C^5(r#/#/ÇÛýÞogéþßÛûãüeý†V#7þÿðc,J~.¶{‹ÊÖsœ¶M·¾i0¶¢.}gâ¬ÃJUaz½Z³sž¤ö#7œûuƒìDD( /øP$4$ '#9п¿ÏÇâuãeº¥ç¢‚S1'Ù­öSçm:Ñùûh¼`Q­é0 j&#/Èç}n±œÖ5¡Õ¿ée-k7áD>ÿ (©•ù³"³,ˆð_°ÿÖþÑÏúürñû5ÑAé øþÜv8Îëêv°Qh§2i ›Ÿ³ö¦þOŸ­;l^55­=)–_’ß—ó±x´F iA‘ /1u?ÖØЈ´”>¯ô_€çøÇÌ>øSzGãö‹ :Ê ˆ)5Qø,jSèH|7¸¯§Ükšãrzá£~b1¦'ýéöHtp¡sHÄ} >‚ZôÅõÍk®ëЛ6(ÁËÍ¢ŽÊ#/”ÎΡ۹X®Ø4Ò¡%Ì4rôuôcѯu¯®¸÷ôÿ—ý.éVI†ž5ŽûÉŽJ£2’ÂÇ¥ßui'¬#7RÕLbŠåoÏ'²ä©U÷JúR™tÇOÏëßõ¤ÉÑ%„÷NP5$S cIƒÂRžOªàñyåÔîfÔz\÷—»h´ã­|‘Ñ5vLHZ²OÆvÑ=zÓÜÃQ“OaÌø`û§Ö_áÿç?½§ÆOå|ì !¦”‰KÈü†M£²>–Ȫ®Ò×Ò¬ˆ”–Ç¢eEv[˜Y0)ø#9IÁÓõïÒh¿ç¯ôòÝãþ"X#/Œ9Â&œÆ’'9æò<"MÅP…sÉ{Ç/_^®®SÏbtnc!Ÿ^À‚–½ä_æóã‡=1Ÿp^÷=‹o£Ô“3£F`›N¿„0 DT>¸Ìfæp᯻ÐÆ4«g?yjZ¿´ad.IY%egÂÊÀ;ŽkCⵘ)_ÖÌÎ-Êæn,…3ö@}ÿoÖП>ýN£ àКŒs¯´Óžõ>ÝŸw¼R…0ñáã@ÀI,aˆ.ïŠmBìáר#/à!ìBš‘Ý’<ïépD@5g7KXW˜hókïEŒÊs©å½|¾B箌G¢ÏŽÎéDun §ä²--£jjÒ<Á.ÜÉç3ûý´í¸~µIBG@þÇþÞG£¿³h‡ÂæŠöoáO5mŸç#Ô¸¾(žÂÐäö†©‹€LDNQ2ŠµÕ_ŠÔfŒ[ÜÔþì<8¸<þ£Dâ³, ÆâÝOûÚ­°OÍŽ¯nÛïpò €Ñƒ‚0! @Bwé>xûÇÙÑŒömÑÑÓð_ÏÉP"j @ÕΩ&vÀ5æ~C«4Ø;)Ÿ/§#7Û0ä±×Ý .Y0'ªÑ[1¾ CÓùYc"l·` #o/£²Ê—Ǩ™¿û#/·Ú_öïoçÄz¹]h¹>#Zœ¤Ï¥õ õsÏ=#/´|o«„¤Š·Æϱ†s›“¥ã×xô Ìçª^ØYÒskñý_JÆa þØ`zŒÊŠ˜ÙÀé„_!½Âmƒ*©d˜hBpe$g¡”Ë…;ÊÙSP½Ëi óï›>+Ã9ç¥X«‘ý¦Ï¹Î_讪æÓ^î·e2"­é“â6Àîî©{ä©-.jˆë–Ö½­äÛb{}>vR(Þ#~”EªØ=ŒSõ¿•^íöO¦êCU˜~PÁÊÂOênÍ #7I4³múUÖ`øåþ‹Ém·ž8«ˆ ³t8ç`yOø'néÐeÏøKèž“Ýúà®GÇÎø‡&ô;3( Ý~S¢>‡Æ9\3ç~[ïäôÕï¹±´ÖT…/ƒÀ땽×ׯqcÃ/¬5ƪQ?碫cËoÇ„f¿Þg°Q›Ù¦ÿƒz3ur¨—p\üv0i(ü#7 ‚’ÈÂD=ÇO7•¯(ƒŒUÜ^ükg-?îxL­ÒÊø)iÃá]nñBi8«ªýÛb7²:{{à›Þ¨*¢Á”Ý©EË·²¬å£Ješ2gºÉ\Xcq[„×èe€4Q|®6YtK¤$š`’c^©õ¹gùÑÇÇmú<Ôäû(ø;‘‡†¡ìG1JཛyrÑkévB¯]ãl¸ Æ%/¥f6?‰+…Ž¯MçØwzß:1gÉë“>k]s©r³–çÒ(³ÑɉÝñ_…f8¢á7|K‹8£·MqáY×kSÔ%Žð~ØÍ+ û)¿~ÞX€à§ˆñS¬Ü®«]ßZþ9cFƒt5ggL\®”j¶ˆ½‰5•ìϦÞz›”ª«»É»ë½½Zj¼3X¯½)¼TùxU‡¦|°zÕÎ}Ih[^Âó#/NÕ€L)ÝP亳«³Ûì1ÚWÕãuñÚäõwÙ“1KÅà]¬¿w—ðÛf§=5õEym:Gëç=Lp›!‘ñ÷ó^uGü0ªºÜ†™cO퇅`øë6†òל»Ÿ%ûÏjøïï—6vP#‡7—‘ÿCqOIÏùõ-2Šq6r$õŒC@àø2»‰ÁåWdÇ-“°F±ÂBjÎg·Å;O[Kâˆq×ïƒï‰øk›?mÝiýå7nò~2:Kø©¤Šá¸N80ïÝàNž.fÄ=;Ê^‹?TLtÖ]ˆ:ðΡÝm¾W¾¹ãoÆÙðÇZu‡#9¡Dt’w}%㢑Œ¿ÅÜyµ~6ðk\ÉÈFj«ÞóÍg¬z]yš+C-í?nçüy:nü¼k#9äÓ$qB–€J)mgÏ!/cÀ꺌$dªÄ–ŽJÃ’ÞÉ3+ß%‰™•]œˆäÃíû¦:”×h(r£'ñÖgÏlkS¾+4.H@¶Êlt‰Œ|Qh~ܺ"¦±X¶æ`G¯•s¼î½vC¬yW=—½ýJ í›ÛH ‡}ªÿËíøÇjäÙÚw§hG¹ãŠ¬&¦M#H™q&>¿ÅÀÀR’+ †Þ_jó«Á1!ÜáBXE÷ôîniTã;§CüTœ<‰S˳ÛÀé’üEÝ?ŧ.Ø9ÁÊ&M~QÌ>Yõ°V”VNm„ÌËÏ'WÐX³O °ã.7ã#9½’sœ•=ÂŽŽù=îÁÝýÕUú—Úð–ý<ˆ‹OÞÉ:;ÝÈá8:1MÈÑgȹš3IQ^å&ìQìM ™ãHó=8üvà‰‚1ˆ>—W´WY3}«GPWæxG&×^-op‡×½ÜÓã}n:÷ð·Ù³ØE*m£òf¥ËŒ]‚Nó…š²—ìîéàç:Ñ*iGå] øýpW~ºpÁMóLùR>y}røà^(Ë8ÑÉ¥Ö¶&d¼ZãêŠ#76YÔÄV‡#7Ü2eŒ ¢ü>“´Fdíd…¥¾£‰Oë?aùw÷y›g‘9~¹ó‘¢|oæ,úà|hk'òSKðyåÚ× ×ú {¸=SVINm‘ø6©¨á‘ÐÿŒÑ= @–ÂÇÖcÞü}^F.!¶œÖÓ“žN—ñ9P‹µ}ruãø_£ öý{òÄIIëñ®”h=¬%%"Ë°ýOVdN êÅ7l0¥}L§»zÑÀè|6¾m>±„Ñœ+ÿÈ×o8žE·¿Kã:Ôß2#7‡2Ó;>zÌrá¶;8¬m%ÈãðGÙÉÈí¤uý¼Çà†ã×Í;HÙÓç"™쿡éúúKý’ñŠ M˜ÐnˆiD;‚ Yü½bJ pÅCüæÉBt®7nå@óŠª#7›€ @¹ÊX‰*¹×qÂÄJìòú)þø/KyNi6¡\ó´r™Ð߃¹Ë³å2OãhÏ…û08yõÛ÷œÒ\ Ø\v i÷â}ôCšÚ¤Ë'7¨zù§«5 èš$E|éÆË«ú`Ù;´ësÚ†§¦·¾(¨¨…Üâ®tN°d4YØqßµ‘¦:OGÇØ¿‚§|Gm½éçõsI1¼fm*åUÒ@‘¡`1D]XŽd—òG&é8È{¬Mšaù´~‹êш’vmR“ŸŒ¼…(jˆÕCˆ8B®œÔˆžÆažl<¦ˆKIìBñ(¤À%ŠÅ!m&ß–_ëxk_~lz_?d>q×mkÞçàxn ƒÌ‹ ƒ4ïÙ„7aܤ}þ•šàÍšHU뤘Q/ü­ žñ€YvFÛCb&@#/Œ>-!\ÆÍfDÚQv ØŸ×#/"½37–O£ óHb‰ _è…|zj>”W®_Ü0¯å›V1#9{|Òµösù3°r¾!™H]p6Al—³»"¬WÂ},'f:¬tÍGEÁ™•pX‚×ÁG£¿m=ö1²2ry¹ŒOÚV- –üv8ÞM˜­v â;Ÿx×x£ŠáuÊaæ@ûFF( ¥dì~š.³ð¿ÊSÆ[òµáa†%£¡á‚Þ/óxþô@?¨"ë%3‚A €'Èù ÎH#9PgïÝ?ïù~‡üœ~Aá×õ#_Ù(²¤"€kWRCÖv¯ç真/ÀÐ#Ö#v´#/z})þ ³ÀW·ô[¤pýŽQ…¯ŽzÆî_êèaÔ>Ȧ¸¤‰þç>ÚŸst[”)‡³˜ÐÏÉ)N2>%tpû>Ý~´n)$ñ ¤mî ±×¤zø_ë»7áÓŽuóñN^¥ç:›ÍŠ›nCôãª*φü9?˜ái‹LÞcõÿ‹/È{ÇG#9#9&4s úÕºÄ (تAqOHåL@A$•ÿV& ˆŠ#/›¿ˆ=Äy¿G_âăO0=Ì•šd:8lœb ›@Vè=ûÊÁE(«ïûV—ßýM2ýºÑ»´'êã6\f&çx‡mZ#9+­Ý¿—ðÑÄL#7#xûDŸiв9q,”$§™…Øü¾7«?ç^ð8}œ‚Cñ––ì|—IO”‚Dd9ªŸ(BD©B€¢[&ÚΓÒyÍû{+“ËÜvü@ÿwÔÅ7Dw¿в¦Û}Y—Œ‡\žíPâìqÙ"ò¹É´:DáKƒTÖ«¦¼ÑAÐ?*ë#Ü(ùþVëng8‘–¢¥SšÀûîdõTmzÌTmEâ£5ß_VÞßËåE0ú„˜ ÆÑmr„‰)ÐDd&È2³V ƒäþ_#7*ñ8Ü5ÐzM|g·B)“Ý:u1‰AááðÙq#/jRž4~iéóì't·³Û‚öïÿf»°4À/J…(1ì,A‰Ù\/»žæo‚!¹‚·œú7fÞ?#¥{s“DæñaÛP1 4v¸À*Ɔš>Z)\oœ1“ÕDfk–¸ÞŽ}÷;9”CT»*r#/¶‰¸ž$×ãÎÅ‚¤ÛűêàùÅ„{“›‚fßØ ÊêµñÝå­× »—„:š* ­@,Ábý—Þ—)ü3MvóØ¢Š‹^÷»UÉd·Rkò!Y6ˆ©–#9#/´ªÎˉf=}ØiP&Ë äßç-ÔG×ßïæÊ#7²çàï­bøJ‡~[†É4ͲÊâkÅIä6|†S°áÂ3Žêá)~&âI–8š=ý§#¨0ŒyeáNZ•É,p†“îºf^ƒÑ*Y^ûc(XèxÑ…Mðã[ÓÃòÌ̆1Ü~Яl¢„©:sìŽvò×ç‹U›k·s¯ñ¸—³Mº>½Ü·Üx”àµ@rÖú]ÓÄØôÍShs´¢<_ãÍáÕPÑéM\ôœÓÚܶp{…¸îÜì‘A¯?‡š|5Õ+Èä¾lì~¨¾DNP ‡}VUfÞd‚Q¾zqÑÊè´i´ éU­Ë&ŒÐϽ‘J©ùs©_7þïˆZiT|® ]â=cÇîºEá|iÄ‚ŒÛ#Ó!„çÜ©7#/Œ•ÄPuï×(yš¾Mþ'”`Œ³žÛå«yÔþZš¹:iµ±e}ýmÝ·sú…)Å…·;l*t…/Ù’öºoXâ«çø¦ÁÊ1{z’^SuçöIû§!ü1ámÈç‡2vIÞϹt=S0…3¶Ü©w¤‹c@2¸(zÊw„‘U$ˆF:`óFRP£)/ ôzr¶Ñ £yQ}ŽÅÂãØÞj5°¹yv*Ñà©ü~Y¿/p1óèŠ]ßô,¹–‘¯OfGÊ3‹)Ò3Ì#7 ¥ Ÿ€ò*õÇ\IÂ×­J:2: çF¥m ßÝyíeL›}¯ä¶Z0çÝó¯¥Âå:y®sÄYÙhÜmÌ-ÇM0ÒV+31ãݧyƒH%Áe«=‡Rü‘ø*,¯”7! 7Výpߺ‚ëe`è†z"ˆ$EÎA®ÜëÔêl‹SPV#9'µ¥ìå¾ZÌAÙª-Åì3ÞÓÑ•óuajßFr®æÞsÞÖ—Uõ|²#9´âÉ׉y¸ÆÞKu«CšØÎœDiûç£OV FyÁsª†n·û áì‘”µ#9V#9«†ÌôÎèRÕ¬íºFïyÅ’´ì˜VÝóé~ý!yùõ’«Ñ'íkÄ0Újì²aPàç>{Ã_-¸¹£UÑlÓsòÝ…ó’ÉͳÍÎS q*,!ÍxÆ8—œâË-*Âö`Àæ ¢Ü“žaKè÷Òâ”)Ž70o¼ÚÊšqø4táäGܬ®¢£U+šo‰]|CŒgmš8åaµ´'O =nÜLÓ\þ½ú—`ìŽÝ‚”U„×oòÉÁáåî,õSùP‰Ì1æ|ȹlÍšìf|HÜå¿—ê¨bD?»ùÆj=×|“jUM@ò ­Cµ.#9#9¨óÉèä“+/jLº¨¶GÃÿY9ì¦~¯™&žR±T÷þ-"eš(bìÓ¨™¡£âö!ÚRtuÏåZ:CkNØipä©œs'„º]¹¿W(L‹zP­ÎÏ‚tšíÌ}òƦ|U^¬px8Ü2ŽÇõ€˜¹zÉ‘y;g‰¿ƒÝgi43Î’HæJLÒ#>ü”ÓÃû—:ûB)ÙӥͿ›¦IÁ{ôÎ3sí2§^W;e•ˆ(¼Õ¨)™¾E7OîùG$§²#/9Öâ€A°AÚñÜ3‘¦BÐÓmí_Uo­Õ8<‹¨æŽÛEb>Ó£§)@+ˆ|,òt˜ñoëR«ÎÇŸê@²3S§&ÁÁ&sHr ×É’µÄ#7cpzÀ¥+ê[ZE€”ãƒÁ)Ì53'žô¯®½éåóì¿d’ÆV~â¼åˆM²åÉ`7m)`[¦ŸƒÃÉ`ò#9-¢ÄKAé<Þ’:ŠcîÔÉè³Â?9!Ú’BL’I}¸èÖŸ=º¯)åëðÙ¶ñèh"V ðQ+´ƒ‘Trú\ÎZüuäƒéÍG'tzïBu~;EŸ;?‡ìiõÜ}ÞÑÕ;Á`ªkç3­Ÿ)uá&(¨ œ;^×#/ÛfyE¹2F{¦ež"ÀtÚ’÷„Ù!“솩Hn;xìw‹Ç<æ&„Ùd…³LWzøš6ÖíÆì´[º>Â40õç½MÌrñBé9k‰ <9Cøòhã«–ô‹ðjºƒÆì¿k†Ø$PV%èÓ#7«·sD‘4ŹvÕxYü5yï7C³ Ö<Ñ3àãž½±ç4¸=j…÷òñ‹ùø¹ù%sÏŽOÃ6^R3Õ-×jÇuàkú¸Ã?{i•ùéÜÒXŒ3ÄIÍffQ+%…3Q* ¤0~bc#/YFÈ(‘Qò-’¾‰<y7¥ÓÌnÔwj‚|#ŸçÖ«–XÓ=aÏ£—VÖqqL‡"…•#7®’1võ)‰ˆ…û{E7#7¡€yÙ£lÀæÙx”š÷È5ýØFN!çFÒF‘ƒÐZ›Ï;Ú’I?\-YÛÍ1|Ñ+e¦"ñp7Š-‚Ó6s¤NO‘¢zÁçßÖ¥kõxnÄv¯Ý†q%Ä#7MsËZ¸Jj¼ÄSã9%Ê–\.*„þ‘ãòs5á†þ¡¯UÓ“/ÚI'ƒm#9&>ûÅþ™lú§Äìiê5°—Ö‰c*×Ö¡~F÷Ò²„„2ÏAJsôu Ž¢¹ó[7m€¼Ç‡G±öMSx#jŠbÌ=a§TD‡$(vž *¶ ät=ZÅ„<-4#0EI^4Š#9Ù_=ñ ¬Évèˆ|ú»Ý †¾Yvá¨hívž‘mõÌì[†µfžËj'#]á«t#7…ÂL‚Ƕ³ùû!¬:Þ…¸ !Þn¸5¬ú(\‘ E˜tˆ2¯Ê/îøb<,X j GÍRñiV¢Ä#7]#/nƶcŒ)ª×% [pµEt¾Çóçfº~¼GlÌךcšpŽDÈÃîFÌÂý jÕN7èÀu4B7¼I9’E3pt–‘rp¡2M·¯$4mŠ§3r !¯ž™2y06hq·^Pí¥¢ä Š ±¹H•ÒévŸ6!çtZÃmËoPB CQ‘o±j׺Ém´Ù$SÙ†—µŠz(ça™ð}E¼·\oœ=t_Yy ¸ºëhD§ f‘,6³0¢ÃsØ>+‹i½Ì¢Û‡ÈƒqŽøuΨhCç|ħðfÊeµû±àu°Ðd£'go¯vLŠHbç ¾_ñ}† ¢a`!v#+à6RV¸#7¹ª'A@îu´X絞úá¤thá–Œ© V¥5¼€â5Õb=˜(çß6Ûý†ÙŒRŽ5§;F<¡Âí÷‚¦ûjî×z<™¥Ñµ¾=PµËøËüü1Ó4mŽŠ6{C¥ÏjO‚­òÀC¬ncY²ú¬ˆ»Š$óç­Od_6ÃHÃ,œ%¢-™XÞŽ¦èGH##7(-­âh@–ì m«Ÿõœü€ax ÞQ&5Çáj-ĵm cZÚ’ËBò#ª†Ú (&çX–Ž#9.GmÖ®á~HÂ&ºõësõ¬#9¸(¸U DèLµ”HN6Fa`ÑÚô”Áý`|~D^ßIg‰9‚ŠÜ¸#xÈC>ô’8CˆxR1ã°ô#96qãË|+°úsºü]Ÿ ¦#7Ë|á?b#¨L\HWÝöçë~UËå\ù`*d[Ù>º‘ŽŽªõ[ [¯Ú·.ÞC(eŸð¹#ª{ãÖ]k´ËzösRì¦EÊʸ¹€%5ÿoã³—ñ÷ûÅå×õ#7#/óï¸ cö” Gà°ÑÁžÑrhúNÏ ;#9ô+Èu\ù¥^'GGãTÁ‚EgI™„eŽ1œ¼c ¿$™ Ñ€!…O²j’#/vLß೶*5×-9Ì<2áÙ_¦;vv#ÛTðÁùÃxË­ŸÏPóT,ÕlÊiœx†ÇÏ"ÔÑ5/õXýß×ì&4‡÷óÒÕ׋]aà9#/ªëVo«åµàyœç°kN<#/|óïæàÜ›BÐ#7NÙ¦à5äyŒ§^_¯WîwO…ý<’пø§ßãC°óË!žPþÀ.Þ00?‰¸~´7µmt³Áž‚ÄOØ4"û0ÀêÁ舀ŠL#9Ô28~ÑpFv:|ÿËû¼,ÌÎ:þçéï”ýÿÍôïönݘ#9§¨ÌQïÌ02„œJW!üÑ{×ËíþôÓêõyã?ç¯/€¯Ëô™ÿƒü!üÉ@P`f¾±##8mÌÿdà’†ù_Þs22þ·ùËe4 !ñ¢¿L þ)ê/xOQ7‹±¸#/¹¡à °‘#/Ìÿm¢¸"lhN4IsþXÿ¬¿Ž¼'§OÚšff›Kÿ™éêÄ8É€ÿ¿HQþ€ÖjªÜ8xúQ»¼½‡r©Ì8¡Ôõ&ÀHN‡‰N\į_3jOg’#ƒMçŽà°ñÄ¡XßËÎŽÛt3ÏD¿™L7 €êGXL¶PÌÙæ<#7ÕSÒsžuHúÅìOH0w>>b~À„F¦>ïÓöû?±ù^{Oò~ÿï/ÕûÐQí;£‘ÇêWÂGPÿ—üþÝ#©û¶ÿsH‡Ô°œ‘~@øA»Ñú ä¹4¸&6ØØÓ³rcb†ÀÃ,îÑû<?íêSN@ÉÀãdvQ ì=»µØâžø—Èz úx" Ýü¿çgßìöß,Èu‡»cÀÖ‹À&xúAô¯:£ü[Ç>žpØ#7㬌wT§|ÿ·ŸÞž5ïÊ ‚š•=‹ØsnZ$Ž&ºÕ^¯dH<¿Ã@ˆåKˆB€JÄ3…„²¼¥ )Ú”UGÜ>í˜æŠmöýQ_‡âþ‚yu{˜62Ë•€ƒ•(£‡ÛÕ¼tø€xof™Ç´!ðÓëϪë~ÃðšÔŽIý_ðRkH\I:0Ž˜¿B#7ð±?öV!ÌJ1mMO¶}½Ôô.D|êÿpÒÁ#;w”uý¡×ÇüŒ¾~'^©Œ‰q©3xïÑìïà—\GwÈX#/þCsxè8¦SàŠr!Ë´ñÜ™5ÀZŠÅh@èhãéRÈi8-CåZTªãrÐø˜éøz˜§”'`yOHzày²3©áê˜õ„9É@i·îs‘8ò„ºf>r=…ó…3÷÷œs1¼ópÄK>×6ÇcP0ÌdÒR… kN°ó.@w¾Ã`^×ÁqL7ÒAôý&¸´A)ìfêKÖuàms§f» ´Â±É8`àâØ¡WÀ:Ãô@ô?d(’[!ò^h~Û&Uéü“·öã›%3úh_ËúBìR{ÿï}~ò|Ó,°ª¹Îë÷ÿ¤ñuãØ44M1„Ô0Íÿ»g¡j¥È0̇}ˆ?õ*5@3¢Ô#/ …¦Â H“­ÙzjbïÝöÝÃÎ5\Ä®âH%Ü„·‹™BÓà’OÓ nu8ýt:ë.²¢¡”¨ó(Èê>?ï;Z¼,V a°Ï‹}f.ɉ1ýŸÔì„ÌÉXÐm?oœ2zê$O†‡Óíºêj¾Ûûíz¢”Dï#/Q>Ųª0Ò|]ƒÞ7„ÀXRHEUì;×G¿Zí@ZÏØc°iÇKjt&<ù¹ç÷nù'AD󚜓/†CÒ‰ú&‡ˆrzêš$œ³ÞrŽµ,F#ìÚp; ¤£?Ëä#/‡)…µ"¿*Äìï›H #7»?Ȫ¤5ò¼ŸãsŸØx‡Æ~ÇÈM#ÏøÇË!,Æ"RB`Aê;ærzÁ9HnÃp=#9™Ÿõ9 Óg4#7Çþ•ÒD$ˬÊOD%ÖÚB—¨aÚÔüžìr–\tˆbÌoŒXÉ%‚ç9ÍRª¨é­VÃú¼8ɤ'wç§@ûŽ¡RÆvyN=róŸa¯YßQûƒŒð9™¸Å"!ÓPó ée£sÄò0Í”7-ÏëΙSnÄ4[x1yPàôˆ`ÈàîfŸ#/§¶—xÇ—ÁšÁš=z€o0úÇí /p¹D¾#7Àò»ÒˆÜ"ì½”~AüÈ'´À €¥>;ÿŸ.º§"xÂx#7㈊†%NO©QÖÿ#/à1ƒm_ßC˜›ÔºˆÛA¦ë­¦Ž7Óñ?Æ4+=ð›#9Ë_Ä…Edyk»Ò%žž ÊBà*pr Q™fÇú=_gÑñmºÔz#9ᥘ+°ÔìÒBZ#6ñ*Mð*ìï|uáœYßEøÎA7!€ á±*mþ¹JÒ¡_ÒGû6|Ž“8q±¡‰ŒM2æ²Ëœæ‡0.{{‡C» ÞAÐw@Ž áÖPm?‡@“ ÿ2#/ÃC¤Öt(ýžðÒÔ#7”yœA:~ð†/Ûõÿ¿â‡gâþÏ/Y 8Ò¾…:½‡Ôþ?ryº#9‘ƒ¡â‡§ÖFÐóx—#7Øk^( ²ÅñÐ{ÄÒk:u•¤#/7Cþ¹ì52dSˆt¿D?Á‘¶a>¹CðÖK¡¿D´£Ü1i;MȧœeŠ/"âC¼¥:nT£Y Æw#/êj`7„—0¢¾Ñ}~…}Á©¬c»ï'ºaPMD)]n»‚¯¨5›œ¯”$ì öéG§…ª*o#9ÄÑ‹ØÃyUb )˜¶L2 XL”!°ŸÎ~Àý<_¡ù‰¸ñþðömYØ_êaWìhD _Êâžæâ?ŸEðÄ‘ÿå”ס·é8q®ž½uI½)2õÊ$Æ96#7é©ë륛¿é~ Fçvu¹†q¸Ü"ÆS4Jë#k4k4õ­Z4Ì´l¦àiõf©4øËQ”â¦îFË•×)M•&íuêI$“7Q¦±IŠ™u©©-ǘÛi»šÌÕ–½f=2³ëÆ]CzÂÕ3XŒ±#7 7„1š¥ÞóY£\fÑLYF5ÈͶÙþH2nÿGÞ¦3BQD+’ã Mÿ‘Š ÖôÀÊ)±&Oä‚=Ì í@Š•Ù’Ll½\Ú‡_›¥ºÇm‘ ãñ§ÑjõæΠGö$D”L"!„þ—°3n©žsYUù°ØÂ(¦›Z3LAðOQ€ê#9=žïâúÓô#õ~"yªvv‘°´ýÂwû-Јtí©d»ÖœÐŠ) ŸcÈ—íßÙÒ´—X>îÔÐÌÚÃÞ˜ŽÄBÓPÚAiNú‹dN…Pî]ê‹5ƒ‘B–Ê)6œ2NŸùmƱœšLñÒôµUœ WÀ«lF‚˜ ‚ Úåwn‰•ðÌËÄ¢{¾IãÔäÖš ¤¯.†T¡vS€ÞP Æ£˜¢P'Öís›²zÍJÉópŸ êÒC‘€k?ÒeË:Ü¿dóv⛯«´{˜¤¥š†$`}›òÕӌݩMÊ"Š\Ù ÁC9‚ºûüϧ£êººÉ‹˜ÂQJ§í=À{ÚÉ>bˆSEu¦ô¶Pj?»#© Ÿ0(˜ 4ð‚(7 €c÷xù¿Xcih3|-p·@ô?Œ€M°i€4µ0PÃúHW}?Ÿ¯†à=ÿŽ/Gˆ@^ðÙ¯Ò '+èvòT/ó´G•oâ9Û zvaˆ$ ¤u|¯c¬¥öçèÖWèßh ú×ÌúÐOÃTM»ÄO“G˜ÜùøŸýá>ú¿Kýÿåü˜w=?#9ûï=#/y~`<`ÐXGÛÉ:îÒ„¡!(CûOHGèp4|^/õøŽàýèx÷G¢%™Ç€ï_ò¿˜ôŸG\ÇŒ‡V?ÇÂÐõëíOØwx‡´} >¢TÀ’sd{€ì}Þ T¸\ƒñ‡¿A)#9À}zxù?·Áº ìܳ”#7Ïìg¿#/‡Ða7P<}·³ÀÇU—ù;<ãftÕæñ=±‰ê)iZˆHˆh‚>£Ô'/”4õWù ØÚ€Ÿ9Á1TëñsØö§™÷þ®Gk¹ÝÞîÚ øÀò„õè~5§kšªlk£(Ÿ9²Ãúk™ñ×îýé'Ïö§ÙĬo}1 n§D>µ6P4ÈQôï5U}ˆ îæ_€ Ã÷ôJM‚\Š‚€ öý?ÖIüàÈ/îò &|χǠg‘ËÄb%¿Œðýì>bƒ{TÏ'HÔ[†¶¶2Ô÷øqx̃f÷1³óò#ç@„éýŸwŠa-šInéKY&a¸w~¶çHzõ ƒ8˳í*¿µoO°òf«ñÄpað^ðòÒ§ÔyÀôñƒY;"HÃî#9±“ĺ&¾åÌã}ŸØvÍŒx4FEÒ·ªx•°c&qã®ü#7J²!{+Q¥GÊJ8™6",øÁ,jªiDãד„K‰825–6Ævåòq‰•î÷}ªnÀlõDL¤-Q¦Ž¼^¼ù»m ´f9¼HÉ—´î„–tˆàõO»ÃœùuùClÔd5´#/$úfî¹ÌX,‘@>ÿ#/¢ l•±VÌ|û'±<C¤²Ä±¢#/Гôí;ÌDùÄj¸P]Š6U+¸wœ§^ ‡ÙáñšŸ)#/öÝi°~ZÏÄ<„a4<<û;_ä0Û#/8Î<‰çQ=ºšd€R!Q•J‡8oDï=ž4óäŸRvzî„|}ž&×ý¼ùþ ·N¡–D™•@_Ü’Ùï\üáþ‡þàÂ4DÐäŸà•yT”+ÿq 8:»ƒ2çF”A04ÁE¼V⎰4ã‹’7–¨`49œ‰ÐtÜÏ^è#7®LD¯_¯™éÝc y¢Wj^#/AÀ!†@íÆÿ.8ó]|gû²~a'âIê*Ž_aþ1ƒôÊÐ5¢Ú ÞAñߤ#7Ÿš„}#7úØ?F^„7½6@žpûa¬3¢rO„%dŸc_‘ò gØ×ÑC*×ÜÁÒ1ý³[ÂÃT»—.F,7¨·­ÊĸòF’¦s+P#/m$˜ÄÙ¶ŠðB!î×PAH?ËlÁ€œÉ€hä*<å°Ã“.ÉPÖƒf$ÛJ” î‘w„¦T€bQMäÃ1GŠôN/ÐÉÁðIÀÞWÇûUWº©}¹×oCM§@ý¿—ÖmùÂQ#7†Y¡ëúóGÔûu3©Z*¦°°'tX*€€G`ˆ=[”õm؇^©çà“ÞÓšœNƒú:-&'œ†õ£¢" ÷~[“ñÿò;Ut U_â}ûËrKóŸHW"ÆÛ0+íÚ!í­¿lBŒ5ƒøÓ+^ê{õÆ¡³ £dÍ2Q_'y[è(Ûš¯JæéÛt†Ê„Ä•š®Û¯<Ñ‚–Œu&R4ÐlýÇzkŸˆ|¿ÏúyÛ~`5‡Bv¤n}Ÿê>öOŸC#9#9’{±&ß|w8õ­±>ÂSOùþ7ÅÄèõB~øj€<Í|ÎsöNó1(‰0Þ#/'¸M<3A24Pš#/ 6\Á“'m)p2nœ¶¡$6凙M œD÷©µ|vêÏw™ëݦ^QZ>>‘ßµêãœ^ñÝ!·îEÒ¸¾aæJ€dá¼ÌÐyx°ý¯ÕEAì­Ù#ÓÌ53ßDî`ÄëèQâ!Ü8ò(åæÀ®dí• ²*‘R²¬öü¾óžÆ?côlŸž™TOalå\¾aã>†³>”Ò{„Çb*¢¡õB­-<ÆôɆjBÞ6Fµ‹æ4|Å´•d’Gêô0}ØÝ¡™Ã¿fµ!@‚š°#7LH4•-Û!§)$Öxú£Î'æ òxÑݤ¹C5ÓI¤ kãþrw±B!ñ:õRq²#½9î >0Oqôêú>¿€ùZ¦íOgD|Áé=ˆpFGG£Ï&,þöz¢'ª_®>àßâ̯«´ÃÇÇÑp}9ÇÖóz?Éùí”0_pi Œí«À3€váè`–¥™ ¡ÑàÏZ@A- Jª JšX¦E¤459ŸqŒ¿®X/×?è(XçØòŸåèOÕkÀzíÊÎöxéühë®$‘¯Ô%øëHæ`ÏïG·]ëÁ€(“Ð>sˆ¾ü•{Ùªu†‚Dsã¯Ã&(C¶?aù`©=Ì}i¡08ã üJUZ*æ1œ(2ý8S•Ë庠ȿ`¿r}iÚ Ÿ•€ÅŒÄÀr{#9L—”áaŒâN¡ ‚K˜´¤!JCü#9ÿ.ïå ‡èwååö_˜3Ùë}Þ\µæüÊEÈ]UqÅ…¢ 2 `NarÏY©Í£;Îò°ö#7€þ¸,úý2ŸØ™‡w?Qˬ'`8#/{9x+ëÞx‡RЫêý:M…%TÜ8òQô½“7<ƒƒóv|}Ò§ =î%ìaãáé,ô¸É$Q¹¨ý:Y"aÀA»lÝØ›ÊN2É$uÜÜI—Œ'ˆc¤ºˆ¢¬:™ŒeüÝc±è³‘Ò ÖssüÈ£—gŠ.4TJ…JÜ>/Hë|O¤sŠ³¥t{PmÚUBP„ ÃOy*¥›æÖÒˆxo€;·¶pbž0ÌX>Z,’/aŸyâ¿«i~,Gž‰ÉÖû v=ÓωäoŒœˆ ßgóŸÇß}äûDGÎ!/ÅvA»Zõõ’'üOa>D÷Ñ’‚' øBÉÓæ5¡\þ(Öè,Råí‚û117:óUó§êüžƒïÙýK¼üÛøþ¯õÿ×P4.éÔ?oå3Ƹüÿã6Ÿn”Ù?À?")TWÞì}µa¾ìÏøS °<ŦaØ°ÉþE]ÅdLøDùç÷1×Ö<ý¬ø+ók÷…OÙR¡òû¨¼åµ‚Á1­ûѱDþ÷?#ð”çä~ºg5[Ä™Áçÿþü;:Êã{8Ö3€ä8}‡ê®Ùßþ„ïñû#{Ó^;í.ó?^Ýèíë–Øò€†5€IPÙd"#9ˆ˜á°ŽfôH#9Ð9`'g× ˜ ÒdU%@ü²°7g½Üä C@OˆzS¼Ðþ©ùý‡6Ø^Ñó¶áú?R¨,þ¨Z8øzL#9 Ì ‚¬a2Lƒ ïz@_`z€Ù|ÁÚ¾)äøô#7®ÌÓ@Ø=qR³Ðƒ#/–=ljÙ7ïßYALçöÿw>@ŒÉ>{“Ið^˜x ßkßaxK£ÄÏbÓ¹uUN ú9 ö£é3ßØg0õ¡ëàlÕ—eS³‚GŠàÐÖ´¨vX,ódì"‚[4í ˆV#/ˆPhxrö–©×ÝâPûÙ®Ÿ6–€ ÖÐQðHÌ"±@mÖŠÔPI±õ=1 Ÿ¹­µÄâ(Ä}yy+ R9ÅèÄ&¶> çd6ÛSS6ÕVClb¤¦+·ñ§Ì:L°ý‘HoöEF›åk-gTÎæûûÿ0ƒ·î?²~_óý&úŸ9=Ç€Ò`T$¨aêõtA4z„ ƨ£b€ß«®}nä@–îë/MÝç^E¿#7mé8â¢bäN^~ßOÅyY‚x9BwËÊ¡8#/áȃ!À#7„Cô¦’ÿ÷YÒ¸ýAϼê ~¶#ÆOÓӟݘNÃÚvÃP—Ïó%̇ö¾töu2(®Æ J3ÑíÛ¼z!ꞃ}€Rðš#Ñ‘WÓév‘ýF#/ê:{<âôˆû>Wßi$‰ ±}7k®’&ÓÕ€¯íŸÇ£c m€týæÕ)9ÒYáZz|kúa©„#7t9i„YþŠá6ø¸HÐÐkX隌3Û1"f aÒ Ш]í=ç/ö÷ÑÜ{À=ž¿ŒcŠÊ1#ìþö–ÁÒHB0Ðò3„üƒR~G»QdþÇ£>çí9PÕG•2jÜ)¯}ls”äI¹.‡0ûN^ç¶téæ¿•#/Æ$ûJ„J#"‡{}€©´|¢ØrüÀy¸‡%…4”ŸaòËÝ#ý2‡í-°Ïœüÿ,ú³G«6ÌxŠn|_ã÷õ^-þè¦?[ñ¢ì|Çk÷Ì`\pW~™Œ਱€D¢ˆª Ç—ŒTßúœF’™øÎWý¹öDv’CIÊ~ ø†R÷öЭ4>~2pÀ¢„KñÒUãQ¥#9›" aõ:4½ÞÓZH¡*$€Cn@Å{F¨m²ìX4ÿ®7ÿZ<€MòMØXÉÏóî½™ ¡õCùßó¼kåý0來H‰­yov÷jù#/#7K` ¨Ä˜>GØv¤œÂÑ‚FÂI×–9 áZ‡éýð\>ªè@Aˆðõ rSŽ=¿¹¹G÷õô—/¬}Êà6økŸÓ/ÌŽ¿†Åkøþû#9åýsK†ØÀ¡0e2BgYa„Ì,Z,ÍJâÔRèÔ6k`Œ“…F¥>â^#9ƒ™¦ëòyI˜àÓÿYH®•#7*#9+èA˜:CJTÌSjÅM?î µ?³ægaš…ùÌÏ#/›*D`[1׈0µç÷B3 hõª /âÈ.&ùI/kÕ‚Ú³ž0\&¾'Jµ¥Ç0oƒ“y†¢#7d)$tìš -iXZ¨IXšÀòÀÒ,b#7úð84b1Æ´ˆükø&û;Ççû~«u¸®E8€‘=™_7ŸÜ·«þ”ýº€˜ú͇#Ôª1UeE@H+ÎáöËÒ¬LG2IÐç×9T¬íiþ¦g6Ëc‚l7È|¶|‚ãQL$a+ðƒƒŠ)úÏâ¨,)uÙ‹´;IO²wÏ7-Ô~Ñ&óÜÖ´ÛRsþd‚TZá#/¡^¬À9wò#9èx0µzVh«¸8$'¨¶¿7³#/«tnÔ·®U>‹pÓvG˜ªˆD#ös[íLOë×s¯×^d£ƒÉȾ;¿Ë¿ó¤met7h·kI4ÓˆÄx Ghdw«¾ t/z7ˆv²yÔ0#/y#7#7†ˆa…!m°„Š¿Aøgˆs„á…&‰(üý?.pßubÖg»íÝÕ­öÄÇç™cïùÞÆháû(¸±¿tûŸ]P¡¼÷ÿ!DÎ_cÛª5Õïa#/òšéöØ4 Õ*,üQ›^^;ʺ™$åFÇžj¶rQþMÜœßÓu.Z6é˜gÕvZ -3]Dv9Q@FøsÒÀAÎΫêˆ7¹óñ?Ѓ:OIó ü]·§£ãkÔ?Üà.;á"Ç£â,œA¥Æ5EK…;%¹ÑùWå£Zïå4«å”THNà¢NúJr?ÍàÁ¹…°W6W°^!#/meù_Da¦éë=¾i’ë„vK#7¢/…%®9´µÿ‰z©T|®öGäup¥5Úë4I6–¶ˆ#/µQ Ù(¬vF­4€é†R_{Æ×X÷2Ýh@vª^`ª}fÈrÔ©œßouÐp´Î¯«„J âÒ‘x»*hšÆàéD™…#9QAE`ÓÁwÒw pÖÒBs}²dºæ1)Rˆò‚é*$ʪ’ÉM–ÛLñG ‹t<» ¶ †”{ö}/\\c¤S!KMn‹¤ËA#7¥¼Ïߎv‰D½n7œJa Ø]Gh ëN.îvåÁ#½iC{ˆð"¯ÂÊóÏn:ó›Mâà>Dîæ`uÊg]]ηX?Œéûô¼ÇHÂe¶fجL›ÒÏcŽmhpªž´9-”0Abh©š4¾=]6ÍH“k<“Ž½7ÛUì­ÓlIL*ŽîÎVL ð ¶*Q¶aA†NwêT ¡l!‡#7W™×i00´ê÷ÿŽh€(Gˆèý^O„|Åߦ^œsâ‹ÜŽ"Álv÷£bôJSá-{T‡õÁÓ‚¼I·*»¬ºÜÄ>I>*‡Æ@Â$Zûï”\²wlž^Pv»#9´¨”XªÄŠ=]Oß­”•õzf2ý´>}o¯7ŸÙw9×O¨Tg¬Ù&W²ôAI½ê„ýлavƒ+sÐás‚€&”‹Aê¯8Â$$ß’bÑ…Ýn™›ßèæÊñþžyÑõ_^>Û?É^,ê<øÙ §c#9gæ“‹ Ñ;_ø(m–Û˜ás€Òovp€GóqИsÏàçÖ”?&ÇòÜ#/ìÿ.…çO¨ø'Wl+wz£¿w öE7nÀSÙщÄ.þ7úy¯¼1Þa ¶ÜòÞº@„Bõ@¤"QOö¼·¹ÐÆ{¾L~¼7xé´šž“@s§¡…Û¦1²S’}¼Ê<Óãšµ‡$)R¼×úµ!£#7|µÂ Öq½’#/„@¤& pÃ…;ã‰RfߣÉÿ/¦#Úûǧ­sƒ°Ù~zì§øMË{ýn:%uÁF?¥x–~º:Š$P&ÎññôÍï°Æm ¯n*d̆A¹6CU{Ù?‹iîv`­w‡iY<½uïvà§Ð"Ó3!.áé»I#7Õ35Ç3ã·§®Ž§g핈”WÛöÁÓŽ†Ñ,g.ÞH‹v¦Š†‘1³oP1Ö‹)JJEÖ@Ì*ÄÔÀSðžÍºòŠÄj¡°’¡9áÌ= )!¿ª#¸Ð‘’©µ¹X]VHòóˆÄ¯WDÅ\~¹Ì`ìZÒf˜Ž›‹ëƒ°rÆÞs ù™%E.¿¿Üý™Ð–fƒ¸²‹zp€ $ ò!Oº|¿ÞQ—€«ÙÇOåûÖ˜‹@ ¡(åÿ'z Ý÷­èàà œQEB=Å#/ ¡ß³›@¾r³ùÁÈØéщùa_Ôjkó'3Ørý?g×ãö½xËB#9¡P#9'0`¾û)ôó¼~XLïü¿Js„p@?€åA@$ÈûPØ·þ]l¿l’Q®}Ɇ$hÒ?ÔàLì—}ÓfÜáÙÁÐvž‚ÀmÜÿ`6ÜnÇ lörä 6v;Nã ǬD™BFÊñ‡úîNç³ÊlxÕsƒN!'†w/õI;®ª"%ƽq¡(r>a!b+Q™a\U纞‰S²_%Üâ#7ˆ^¿¸W$û~ú{´¬šlIH# u tä—k~±&òžäåBz¡R¨>Íþ¯>;t~²Byøsµ“±rü½ýwº[“÷Â0õðÕ¨qúcú]ßí¨³?.ϯÚ^“Bz<Ö– ý$zá}{9+Ò ÌVœ4¢ÖH65h.­1¶Lµ%D#7#7¦ <…“1aq–} _ðáøƒ™ƒTD .D¢õ_øÿÉö«ÚlÖRÆ™HËbÅú-ðºÃñž«³¼èi¼èÝu*f‘‡íÿ ÚŸXøšWçCÆ'á1YwmÙ¿Ì xž'üqôDUUUX¾ŸEL„!C»8`ÉÒö÷µ€I¹3:wöšÛþ‡ý?.Áìì6^ETV"#Êù»ÇúÍ{{ŒXg·*’bÒT›nOØ'“gSç“êF„-°3b+#7BG?p@!Pgµ{ª¶Õ±&´ ‰{hÊzG?öΞÇ8su@°ïM¤Jàr‘˜Ò Ò*y¶ýFÁC©È Ú¨ü!#/½•œw#9-€Ñ!àƒ!Èœ¶@ÒíÈÐvÖððìdïŒèM<"¥´e ´—E¢#sûŠ˜6û† š¼ccFC‡?ï¶ïpùy¬ŒPknœ¼'XŽ£)¦2ᶷ®3NÉ“ž5’Ne¬JÒyɘ¶ >)¯ê¯ÕÕ#‚ïaï5Zl&DØëþœÂˆoóÈa»FMÃfº"fÑï%_KÄìcBr9‘Ðwy*“ü9Ž}7ÑÌM|9ÎÂãQò sÀÒ5ÿn`H5‘êšú¼}8÷ü¼ü¾{ßj(ˆ“!!"«åD´°Þüðzä×Ü­ee™hƒ6ªU;¢iÔˆ™2ñ6Àz/«<€z66ñE0pyŠ÷ܤL:ˆ\ g9­;Í–I#7ÌΈœÃ¬! çpM/_ è¢Ü?¿©ç™D”NכǜO1ÛÐç#9Mw…ðÑ ³,':ãÊÒ§(ôÆ8AêlK›j£âM#9¬Þ‡@+û¶*iôý7°o‘ô|A¢»i;NÓ£å %_aØ4s;¤™4JÅ{oŒa !–¿E‚ˆ 6êVŒ4 õIYàÞAÆ=)ÓÄ-œšOLýMëÙömËÙ‡#ÛÝîuÈw0;þ¥ƒÅŠ׳î4:ŒÀöÁb£¹×v#Ãv0Hrˆvß$tž3#±;×U¹´êPVoÂs#7ÎÞÝà1ÚÓϬ‡G–Aˆƒ9qÿ«”Hô¤$ÐC”ètM¤(zuÔy”zLGa!ˆŠì7äÖÍ ðF(kÅzפÐxl<ŠRΔÉí+Ðá5œNL`xüÌ”W>P „hÑß߸ŸŠHHÓ°³§pC€Ô³‘“€+ÆvVšyµ‹œRI $E˜¨COLê^·ÎЪ0#9³WKoTÝ¥ÞéÈРƓ\­|¾C$[¾È; ±z²‡#ΆB¬ITÁë‹cšìdzÔ9Æu˜ÔÊd˜í¦†tÆÚK³/Å9,^Ƙ‚ìÔ‹$£ÊcËc°ì7L{nˆÓ™ÁŒ”ÐZD’N_+]àYÂN’è9ìW]ØÞÒÁÉÛˆxúóS0c-Š¼Ì¸ó3&\ÌÌËf5•fY™$«³kÊGê˃ƒ“¦w’½B÷~:Q°lcRt<;R Œƒ£LNYáÄÖ·*j)Û´ÍÞ%–zœ}œÝC`ÄÜ™žµ@£!Žª‰‘0„53„l³v2åèv쳇¯''#KIÒÐÝÙxN9òÒPfñ=ƒ©?o™.ó ‰¦Á¶Àe„M,‘°²L’ÄÂd· 놕ß׈´Œ»‚Ý25g½û+Ú†µL ÍÄ,Y©Ù%¹/§4ŒkcÞMïN½$}:Xì6úÏc=* ØŠ­‘2Áuuàôõ†²iÉ!Üf#”ÑJ#9 µ·#/ñˆßúÐSíyxÅEVŽÓ=DuâˆôÇnS#/ÿ =­ÏÓÔëgíx,#733xd„œ=í¸ÔŽÇœ×g™Í.Bîã sôÒ6 `v¾}>Ê Z[>ëãÓøZñOfDgEAz1çp¾Ã«¼¡ÜâRu¯’u÷ 'ÉÒdVâFètË;sø ×D´[!¹“‘›Ú­·\&»œq½Ø1×¢âÒ¬*: Y;÷>iÙðx¹Õ;³¬²œÜhíÚÇ6Ç–\¹X°øq¦6q} –^aRyÀ´&§QD^§(Mp&LÌÚlÍdG¯ÓÉ9|Q\¢+F“@x% ‘!p¡®ys4„æ °f1ØìdÄ£#9ªvþ¿Ï‡úÛˆ‡ÀM7P,œa¹#/òÀä…C¼TÖX“Maz¿#&‡EReîÏd³ÀìÔۚȖ]ƒÉb°¢MÏ@ÁÐî2úW¢ë‰›åäÎòPj…†ž¥¼$åꥢ©¥h†ÖÖüÙÙÀ‡`ƒd‚#Ôòkf‹¤EáСˆ¼SЛa1Ù\Z¢0ïǨÊ3u3ŒvžÕCs•Êó6²Õvç«&ä,Ħié˲±ÌLò$ãG‰ð÷Ù:ƒón‚I¾&ðÒþlJ u70Øn3]BÊ#9Dj”ÒÊB’Y#9,`Ü¡({àtêT¡‚)Žu6ÛM&ÒC`r`qœ8ÃY­“pÔPàâY™rÃh°ãÄÒKo&ıa#§y#9i™„óUTlÙbÖRÇeá- ¥Štì$nÜïaóUìÁ:YC£8z§ j¢#\qIÝñªõŽh}Çf;v`dækÇsc™˜ †!¥(’Yf‚'ˆò9!³àiñgäʆ¡2H€‰Á,áR,#9©Ø3lB§— •Òô9‹) C„ñ;d'”ó5£Ï܆‡¤µ8Éåç‹¥w¯Pw„ô¾»ÞôCÌ`«ÄØÉx&s°é8C}Ùa½` BùCb =ÑE*³ØLl©~pô×Åë½*ÙÛ:õæ‹Mì`Þ#9Á :Ê_‡ÉêÞ…Îo4†±µÎÞPÐÚ’¸ú´ž•Ýz߯žoœ¸Ó0FA‚A#9¤6Æ@Á ì Æ{ú†Á-ÔǺ( È 7K*É&Ò”#/ƒ–äJ‚yËf°,(ý½¬ãäjcú<#9k¬ †@(§ÑÜ}‡¨©—É $¶’a’“Þ›Y¶q#7ñD5 ã×ô>ó)™&0ŒÎ§ò†‘ãϾ(φ ú»EÕîxî™ïsEª?¨s"¥õzoƒ3Dþ§ô HþÄDA`p¹†,ˆ'|m‚ZýCþDÞ¬|™P†Ó§wÒø5iú‘¦wõú¸ôAó‹Šâb¯wQwý厛ß.ï‹À8{¶vœ 6^ËbÑ0¢´‡¨Á}‰ïT ÃÔtÿbð"e˜abe⃀ ±R ©åï÷½y'§ƒ‚±ÑÈŽþ`ç§øìÿ*ô{¦Y‡úÿÙ8u-Ed·søÒ€L$}%LUD£z“åTKçï¼Ôö—R”[3d”gZ¿•°=žÏ‡¼}Ãé,#´ø1ïõiýD¿Aè1åÄ·ô?›Ð‡Ü‘DÈ¤É BŒÄ­íÝD›ñÝS2”k¤©âvsÔ€ûzõè/ È:LgOqñªºL†¤ZÞ^Ø 2AA‚ˆû÷«ETV{ÓîåàŠé$><çt¨ÜvÍö6ôyû{ÑSÊ@Ùð*(¬\ùÕߎؘ|zþÑúQÿ@lÈ™(Œ9(.(/»®#9q|Ï™%÷xm#/ïã´ž‡ß¹œ?àQ᪢yô;‡Ê<¥ÉîhÌN!ðWÀý%ö6#7`O[hÙÓj3 Sâ7ÅÔ¯!JŠ| ûºš"€Ž8aí„0$t}ÏšÇð–eM"7!:©!à©æI¸¼>ŒC¨‡aŒ ‘d)Ó´"w²\ñÏÍöZL˜ieÝ«†ü›9’dn i³/6”ÊfÌF¹hȉ«ØãÁNF&ÐR´SšØ§~bðÌ g0剆#hk@ÿ#9¨BXƒŸwÈy³æsfäfŸK'ìÒjqH‰Ëª‹åݸóCÔ9îÈ*ÒÐ_Ô™#9XPežÿ˜*#94œlF>#БÖ+‹eùÉÜæ½Ð ­=#/:³zíÂä¾ ×ý¦B¹OžÕë:%`çF‡«c·Ä ŽûáÝÈ<=7hÿ2I>#/’g>íÉq“P÷Ê,+ P”:îëß긾€U_I¬m\´U-2Í¥IJ?ÎGÌO#/#/÷KJ'óÀ`C„BÌ#9q2€Z²«Ý`­*Úîíj¹]…GD%E•|LíáèÔ}Ènˆ|¾ÓɨþÚgLEU&°€áŸ<Õ!ö4J88ãpƒiI•¨•¶¹x¦VÖe®m8N“};ìD±„°C³Ðv*¡ÌØ6¡Â¡ÿEuI0z›ñ潑¦½Š”’bÞ®»xõM·7©½Ms]‰Fîí——]F¹nþžmâæé‹sˆî·7M’²•ÓIÉ{[§ÉäòÝ'¨a¶¥\ J ‘“úñ#7ýH.V‹?ù¤Ù6An¶ßj¾·Ïi|ÜDù®l¿Ábº#/óÇ#ceîô¬z„UH¬{CÅó„÷á~Ÿdÿ¹“»ñ+“TS$ÍìÎèÄè‡rë_œäV(<Xn¸óÓµ¦,e°¹"G¼·ÌðÍÂù¿Bk¦RÀ ®#ÃIvœ'Î3ѤtÂËCJ\—!DÆ#9 ”M¼±eªiöãÔ‰¡¿oE®?ÜíÔ!#/ɘAå ŽH9#94—‚6ÍLÍH\¿.¿êñ+zÖÃR+j,ÁŒ]G.Ó;žFæ8±‰°è#7ºðþáà3~æ…Ü^>aˆ_/=ÙEí‡ï5…Øx6UÖ^€}|ÆÜ.z½·D´ yyJ±êàÃðþ‚cÖq‚vI'ÛWV£®2a ¸ë O8ùõµFçwª]“ó`'ä„#/b#9bIìgIê۷ט¦€}]yïƒXzÞKJäÕ·x?"7îÃŶǴ¼gBspÞ/%Ç8-¥Y ŒAŸÓ3öîb™ íüƒÍ’f]¶tô¶“è~ü>;„E™fXF'¯Õ÷§£Á<ǽà J/Tù°þ:iy¾Ï(ü¯³àõ}° 8èöQ#ÐÓv H ’+ó#/íèÓY÷˜ž¦YŠ¥P:…§gr´$ñ¢L`ÅUAÆ\£ð“h8AêLåûtkX™PÐ]|ùWæÊ¡i¼B˜Ì‘µÙqU#74„¼½¾[òÎÀõòü¿i^¹ŒÉ–&1ŒšþIÔŠ÷$ݾ˜£ä1qb \¸âý”ˆÓX¨¶Ñ¶Ù6Ôm“ÍXÒM”IQ’±Y´«XšU%¤š¢ÑZd#ÀPA3#/$ªÒ3´©óé]÷áxkóÿ¿š¯×h‰ñ‰á#9Ð#/‹@4#/˜¶@Ò̦Hhe¢ Àz ÙÇ|„×¼å¥;–¾—É‹š+w`EÂýVæ@¡€ðÐØ늣¥D†,֦跤´#æ#/_ÈB= #/["›û¡à¬<™g5„øRyJTÏÎb $V&zq£l ê‰ppLx)·JæÆksE·½Ávž#/naG0!à.Ô:ïvêC°Ãi$îñ}:I€°$úMµ%kheªÛ ªÙb#/ôîTÅ@Ô#/v#/˜øq@î{yä³ÉêB ƶ#7&ëˆ±åŒ 20Ù#DŸÙ¶.ñDµ™!!aÞDú¶SÊ_£ä<$yÙL &YvˆôíïÆ#/È‚‚8öŠh¿~‰Ý5dÚ"Ù¦¤ÚiWÑÍ\¶(’ÔV®mÍnj¹LÔ)P”[3¨©-± ª¥¬±Š#9§íÝûßE›7 ÙÖçÅëß…#9°Q @ƒÄö3 Ã#7ÞvÜêßo¿®g¯à}*8;9ÑBE•3€aÏñMJ!óè¤@êûÏY¯ÖÏvR„db¾ðû˜œCͯ›*>“õû?áü?G÷‡äÿwû:Ÿ4¨žø*Yù/ü"@~VB€,ïõYãT^(¡Š¬Ý˜K˜¢dî°•uP>îX##7÷½#/ à €†áUL4>ã˜qÐô<<;¬ÒMØnÒcƒãÍÀÙCyC²ÿzE] 7ƒøÏã·ëÙZ3úê£A¹›êÌ`gêSÁ‹ñóÍ»ÏJ‹ I?Ro~e%ã7—«Š»£”‰Û|CÔF þ©=è½±žÞó¼¼sñÌþ\{˜9°dPÈG—òýghÁ"$óîÔ÷vŸžèyJó¦Á rÂ.*‰šp6‡ú²ù‰«ñÚ TbôAD½ËpUx4“ÎŒ©m9‡Fyñ°t]ƒd@¡ü°¦Œ8'blèàŸ¯ÃÕý1éOaø{OWˇ½!{{ÌžÔ¸#/hH$óPkÞošßº~íh4Oó&ˆC[eoð›Ï.g¨†ÁøuŸ$/'¼=põ‡Á/ñ-õZ=ßçuàÅEü:^‡¸˜AÇðyz®3ÍÑ÷~.™‚]ê;Âé#"Oȶ¡Èü_«PóÑD¡¢=û¿¹ù׆œH3Üóàwï O³ÀÅÓáþÏPht"kõ’Cþ„$œüý!#/v/%=IGsѯ}¥¡¸pƒF±• ·°dº™œ%-ù q)qûÉ…þœ¥~Ï‚ƲÛoMÞfÌîÖø=Þ™ bÏ=\ü€ö¾~óNþíR¥kTìQ”Ê°—›«ô$<ó‘:1Œ¶m7~ï^aŒ]À¸ÁÖ¬zý Ë çk ÊQDûû14礂ƒ¬&“9%ÊæQg”@üx<àüÀã‚#/IèZŒð@’Š!#/ f>^— ’0LzWyg¶–ùÙH<ïØ÷Û–pYãˆ÷mþ"üœž.ˆ‡!Ù|,žÞþRwȶ+è˜C‚žÇe}Ïd©i¼\¥É‡Êü¸%ò k~Ç= neå^SÓÀßùA8VùŽë1{|"7¼Æ‡Í¼í>yDÀ¶1Ó?›Mô£r|.: n`ïZÀèðz8émÇNÕÙtðã¬v×<®ãŽ(ÇmYŽ…—¼¨Ù¨mÖÙ*e\£·¶xé„í©ç7GM½™¡èår£Ãaºô¾¢ëÛž=q•!†çœs$D<¥°p_MζuäÛ;Piµpä_ †ÀþŽà”ìØÁ»ô»cSnæ}Ñjv£%‚±Ú·bÊR-Ѷµ˜kS¼¨Ñ0¤÷"(ÀZ"¸ÌDy^Þ­š›¥ÔW°c•˜`S>ežÿ~fì:ôÞ}8à ,L†êyA ˜Ð .mý£‚uíá&<õÏÕ*jòð¢„G·³€ž„Ðñ>º“ÔP!Ÿ˜}>e!õûR¡ýDÐì9NÿjU#/rá±°íÛ«t°/¬Aî îlKpAªM–ÃpZòd½YòK[?i`ë¿Wûº°#7-ž5‘Ñ&˜òî6·6(LlçT#7fÇ=ÎB:ƒ‰!Û(2nrS¯"-UJ– ˆ# ‡ggŒû9ï’&peúTÉ­‹.ëÅdFÇfšˆÔ;ˆø¼Ë|¾Z'Ø÷! ÷í¨`ªA0Á1é êdšž9ÓÛ^‡ë{zvéÐ66í.Å5c^‡CÞK#!ƒ”Ù;8øY:a ¼3yú‡‡CÛôLK"‰d9â¾^¬7íî‚$FKòŸÙôèv:úÍ8oò5Íçáe¤§bQg¨åC”­©µ4{¦¦¥›GíñõdG‘®¤‰8¡¾Ý/„•?R:~®j}S¥‚#/•Ý›=¼vVLÉ›r9±Cû~|yE„¿Ÿ ;ùR '¸ˆè:e0¾5¬ó«>‘õm¶ý¼o ÷¤õÈ$ð»èW¯r†áR›Z£E™N`”ˆ‡ ¢ („H•)FœÊË@¥1 Pq\$Ñ!RÃænÒsVü(¦i#/ØÁÃë HI 6aßÏÀlÚœÀ€ˆ56B¤Xª:Gn´Î…^P‹È¸•KÊ'Ðo—SX’(‚ µ‹)´P‰9žgDbj󫦹TÅU3žô%ÊßN™ytD#7¬ßymá¨Ù#7ðˆ”ÇØCîäþÆÓu§9ÞN½5†a˜:ͺ¤+³_.åÎÀéG5§(Ѐ fm98)kÊ•Nì£õßVö’`Ç÷ë®a‹:”6ÖQÓÜàÅSm¶Ð|áôqpë“ic"‚ã]‘-nMÔ6Qxq 3@Ca¯#7J´¶*xÙ#7CP™8‡êÞ¤ ˆé€Q(!¸y„±4'D K;ÍÃ’Y¨†È=#9y,'BRtÔJ‘Š0%‚Y"q{›Ý•êøvañ¢Õ³žåZŒ÷®0ž‚à© Ú£BŒ%éägU:#ÞÂêp:ºv¶fãlH‡H‘€ÈPHÙ¬¸†í¢…10¢„ ¥žf–´e”m¸yE±‡7#7²’X›–2B–’ú †°034²„Ó‘AŽH¢¦ `^f*™±‡N´2vt†¥¶ˆ¡Áøü§q#–ÛÖã¿S’|0¯×RpŠ¥Nf+J(X„°8ã΀,WÎæ»ìf柬|ÌÑ•#9A¶ñ!£ú³ã‹ê;´—4èm€¾v#9x¼ôq%Û¤¾x彿¡ú ¤ƒê=@ fI„™[{÷uÿÊó»²=ŽÄ“K%ëºBÎ]wØä}óHrgêIÆÎ7Ö#7•]ToÜýr×lHY5½ŸwãôÛè¿{#7`ÖÍðìÚ4pêKœåÖ.}•ßf²0Er֦Ĺ².ñëgœN°;xØ-&Å#9©T(âöÇÑì?ÌeȘC >SЀ"ÆÁ‡+’÷Z‚ t‡˜3–K'Q½; æ=¢Tì‡ÇÇUE$ŸDÎî7’„M±¦1±V:ª¬¢|‰’ŒRd²˜æ¯‰Ì<þ_™ºÆùäMHž›+ D4,BFØmiÁä`f³3€"?0$ªiZgX‰¨73#7E³€HßÒUš2ºœQlM#H“ë§jÝj.½«¤ªó®¤‰,yõWB;/o³@yBFÊ…6d~ÂÛ‡«\8 )ÎLˆuJI'¼<ç„×—g‡‘TÓÚˆ$ð56rB±Z1xˆ"ŠFÓ½ÎQSM ù\£-q€ðæËóéN̤±V‘ Û/a¦Œ0‰ãiïq#71-äÔPìC® — f´ÒÓטnt T7Eö˜’+å÷Ù˜ò(ú\ŽIHÈÝ€v(´BnÍ[Gj­àv³Â¤F.ƒ‰†ú:“-²n±ç_Hd¿—A¶ÜmðYϧ9,ÀË$™£‡&јÅ\ˆ#9…m#9Žëäxa©þÆ®€ ¡‰ÌF†›ÚfÌF=OfFŒ±B4ÔµÀû|u³Éë€ÁpÁ‡ÔóMzÚÆb^QG¬QĆ½]#9T¨(ÆT½‰R%#3¦Œ®bkÙ¸pÛl0KQkI¹…+J0¨¨1E kY/@®¸úëRÈÒ9£6sCg,P¦c]3 ¹XäU^Ó–64ÁQq¡¹#7š•µÍ…vBu¨«cZG;çôvÍõgÚyÆ›í+|ëo2|™wè¼LGª=ÜÔzÉO¶¨IŠ.0°Ñ«Áµ$ï^—SJ¨Ä÷‘ãwH*NèªÕs¾²ÜZë ìŽv§}Ó£œÄXÚÅ‹ýi¿Ö›!„P›§}0žÚZµaÖÉ#7¡{;Hª‡(,ÌˆÉ V1$®F)¾Sk5«ãiqTßF\•”£’Õ^#9,ìeVGaÙ†L—^^2ÂRª‚iÙ“€’lÃ`ä`½×-N …›Q˜&S bRÕ£a Ó!¨Ð¢²h-2ÃQ ³#&̓—LLbíZÁC¹O‹M#9˘¢É/®›ŒO°šÍ9Ÿ×¸ŽB™òòiðã³lÇJ‡Œ?2s›Ñ;V_¯}©aóo\#2ÕÖ"3T†èÈcàÙœ¬¹G"+Š&‘¶ r7¤ùym c4 ÕØ42ê:ÔÁ«ÎlüÅ_ßïû:Ÿ6ô1˜o‡ˆÐH†%€d#/òè a=g/»§÷Â{¸›ß#9Âq.p…À&Ê‹ž @LgÕí¥$਀Âàè³#7,"HUš‰!rcGL’G1Õ4! ARI¡R òéˆ80µgT© å &D1#/á3Úl6tà1@j…Ä‚4Ù‰$4í#7Ñ7EMÔ;zy‡tü M®a8q›ÛÁ9ó>gÏ°æ1>H|©ìëb‚¦·˜®éW»5…ú€õ1´ ‘\í^8ì!+ÓI¾|Å?Šs83¥®+V\}&š9×sP5ž>Ž.Žeñ<Õ‹ÁøÜ&œ&ý¸ðIûå\™ó)¥SmL¯ZÍý7#òúØj=‰"‹±ë½;›+“‰Þütz•OÉDA!Mh©›b¾uÏK\Ñ °6ŠAJÔ¥#’¤AC@(Њ4¢´ŠÔÔ£’- ¥ ˜b!„1 †à(A"õ?'AôüVÂx’¡·êö¼8cX3T æs¿\’iK(@ ꃩÓãðNÓÆ2jïÀã]˜8ŸipD€O1‚‚24"#,É’™e©šdÏ°ÝI¥MQi3%\êLI’ÛH`ÅDÒ¦AM)¢&[Fo Ü׿na“Zf,“D¦VÊÆ1fbJDÓ62b’"ˆ‘TPÄ¥‰¥ò÷Q´–E#9#73#9IIfdÚ˜Lš5•Q"™”Â(Íb´Å-™D¤ÉL¦ ¥*LÄh4ͤÓJE“H’÷÷|•Ýú¨œfïu1å!YK÷#/Kgºr×@b×éejªû©|!nÌkåýWf„xìƒ\²m3wHPÃ×ë8–*r°ÀKJŽœ±€ÁÙ¸’[L%ˆ~ÎSƒbÌ)4ÞúÌÿpÓ”4ÈÄg#7Žßˆyò¾QB²˜ÿ#9>1†:ºr0üݺGrÀþ³2F@°e~m¾äœÈyhM|p‹d½MiüéhºD!ÂëÂáÓŠ/3B ù‚æÝ‹Ò‘´Ê4 o~®ºÃI?¹Œ ÐL±ï§Ãì‚öT°»ñÄ/Jh6&Û pÀÈèÐÂd© ®ÉpóŸDäp‚'Aëšb$¦€™¤ ¤‘²³,¥¨ÄlÆZe˜ %’™òã\ù÷øx™˜˜¢ýµ›Ö%tu…OºT{3ìy“•Sy¹Æzôa#9ÒVvˆHù2#9g¿PÁŸ{·}å·ïŽýZt¦p0˜méú 0^o¨f#ðsa9#/^ÞÃåô§ÝÁy?¥!¿š}õ=C‰¼RõÈPõ¬àùj.oùþa‰Š8öri/bôBˆˆ[>Æøl÷+Ù ÛÊíï¤ß¿±¥˜@¬+H!„”F’€—uƒ/£½6üÙèüø —o½i5{Ÿû2ï«÷ÀóÓÎ(ëŠF ¾çÝUUÎäI*"g¼îSqOœšb—xqî F•áñçü‚W¬Mš1–´½°Zº#9¤–Úm±£ö¡qôâÍÙBiÒ‰]õ+{ëŽ1ï5k´„v ”©ZlíªÂúÙm„<çk”4₶ŠÑÌ0º#/fŸdÚӛÈA²Ø’kä±£Uñk|˜kPK¡BÀðs]IµØZv¹¤¢ xg+T¡”Ô DqŽ¥¹¦Ä÷š5Ý. lƒ6»™ä¬ ®„Ð"¥=Kî{žv§-á$Hµ¨1䙚Œñ¡GÄ#/:Š_rûà «²lyÑã4›Ì€Ä(Ž¤ÄÑ<Æ'a\îë6ŸÚc›ÀTœñD£ŽÎw,Bnb>¬£¡”¤$ŒÙ‚f8wâB)Ø!ó‰ï=HóËô}7M&ŠÐô[rL€!U@@@ÊÝ€ê#9ÞY¤ÂºúýG@ñò³óúýD`C zü?:ìÆ?¸ïµð‚R‘Þ›J\¤Þˆ‹ÐG#‚¨•óhAº Ç¯“õxPl“ñý-úBÆXÑHOE;ôæûöá3·º„+‡çï-~Äïé_/›GhÎDL³ŠB‘OÇj…°Y¥]£úáÌîïâw+ï<7;6αã5ùó,ö©'XAd’Ny9#m˜À˜ÖpÌ.DÜC`oŸƒø?QŽ>í9¢ºŒH 2#T@êW@%Lì_Å[Tc}¡àl°³gœk'¡T#9«s’K?µ©MÔM²$ò|ÍÑ“Q~[§Éãz¬Ëy5¡ä„š©AêX<®dó"ë§=̓máÆfÊç×75§Iœê<ÃT™kmšxï23Làj] $ Æ3FEZ’’ØHbã!­DH²Åút¿‹[6lÖf;Y5­sîò[¸4UÛ%Xz•º”(%©ñj ž»µôc¨íÐ*^¤Ùty‚Æ §„Í…;­ˆÔŒNË=dÙO¸ã›fRqd·ÂÞÏÂ$u·ÞgS7nP mŽGdÅÖ\å8“F ÖŸjwÀÄí“­#€`r»£L‹Ž7ršÕ5Ž¦¢€La;&šÌËIÌ3š&Nøä馩•$T•FŸ\;»Æ0µòÏyÛ)í©·¸K=`:pa8 ç¦¸â,uÄq&_}ò ém™g´ø袓0!®4ÓS±gwf«È„ ²oµæŒ¨©ÁÛ;HКPhQ¹ª˜v;ñü"†ñnåé¡Ø`׃ê•írQë‡D³h‰Èö“uÉñáAéæmœ^¶Ôæì•2Cq§<5œófÌ÷¬‹$RÖ/}Vg&µœAŠêø§qn= é;¤Î€tî‡Ò6z«vôÙ,¡âxô£mR›XX(KMÂÃ^Œ\ÜÇ-yr´úvÔ#9ö±¥5R Œ\D†ˆu#/ŒE)i%6U–B‰Lò=D?$o:“8X¥'çf‘ù§X@8†å…l‰ÛC·ع11N!\L¬+º"À$Ƥèzeˆ ,8XÛGäß×FôqÁ¬Å/´„ÒeÓ'Ù’Ì-í”ãÅ݆j6Ú9²Á¸Fúnr¯»¸š±o/=Ë/ppÖí›jŽË8ó„5¦1®Sœ[O›s0¶ë4ß^#7ÖÍVÜÙÕÖžad8°¹üçv§Æß¾ÖVë(“U3(d2SÏg3±ÊäAQviJ @ôž_&çzÝ8¼:ä[ ²0Ýv=IÛƒùT .ÌìA¤E¤ j0âÙÌ@Ž$ŽdÃ.x'‹HÃÀŠÙaÇ$Ž’3œ–A&ëŠC½@ãu2…¬9ÆI!šÃ©ø [ç”>FË$sxÕ¶Zˆx`ŸÙÿEFV;Ä p©ì—nÚ2u+ž|LŠVŸT›ïŽY ÜåœÒaÄÎkƒ <ïÊé&¬#7P:±yÉ爓Ô6Šôçh±šz,®²óžð8èOѺï#¬ñ:nu¾P¸F†ãj¼ãfcNn'òú[!ÍŽ Ë@:ÃбŠ!™Ũ mà…»ìhÚ°2¬Fvµ‚bÖÄj`Ó—ÆU“#7—Þߊ~ª@4LbîÅﮬ]"ÐÖÎðâ„-šêàˆ0pæR9>vÄÈÔ¹äõ;•1‡‡Z_*4¬#‹£+@;ÁÆ Å˽«½°‹¸3ÊØÆ›,°Î¢…h#7Ô€‚ŸtÈ/vR;Hôa˜"„ѦƒX{û‡QëŽÃ\œÃ!C*º¦ÞTj…$”ÆI™’š”6$ 649©†ƒ³*F¸ìÍfÄa8¬sdÅ)¡ÎQ`nÄHÇ ’ÉP9qœÍƒ%ždFñÇ$hä3³;Âf*†zŽM¤°(dXÀDÈ ´ÌÔçFzqêÉ0F ‰†Ìnéhg4g.3i7& !Ɩꎃ ä4,N£‚niuA´f{1Ò¶Ör@Zy·Õ ÙSmÌ;HI¶8fÁ,#7–l›Øŵšf¢Ì5ÎKaØk#//+ÆÔ–1=G{›M”Ë jF–ÜÑ€–D3a¨`œI2%‹„°9¦ƒ‘v@‘æ°Ã„Oi¡`Ž’R¥l™£&jÍûÉV-RI‚‡òó0}%JD(`8¬ s@;ØyoŠ¢Û &ŽÉ”Ö˜"09þ^Ïêó¨þ~A÷y<Ä”!—¯‹kϹÖ/žò®ck`–©Pû³óúÇ#/â0· UÞé|‡®)ºJtéò‚¤J":B%RP¢$q!Å`–ÅÕ #ä @Ù k#/š@ j‚\$€¤à´÷å¶~EøºMƒ±ZONâÌ?‡ã}þ{«³yÄÔìˆUÝåŒ?êšS¶HÚwð—ŒYô™zmpÿ$m©œw¹gW×kƒW)LÖã&ìê;¬¢‹’,í ι}ö¸qB¬8ºD6ró5Ä!!A+…—ÅASQÅ®x½Õº©•Sƒ‹;¶å“ÔêÎ/ƒ‡ä#´NÌM(W#¬9u9•8‘בus’"j IÖxz@Û³#/E†çƒP#9d;Nh¸:ƒ½Í*I2=#/îCÁ ìónöì(‚]nÝ8ÑÔ¤®êúmvU¾ª&bv#/ÀåÜlhA#7Æb1T8¨ƒ¤_7¾Jç #7[ªrÖÈgË·¤ƒ#7Hnh›NÉ8¥]bj J£­z’@Ѫƒj¥Y÷}Þ :>) Å`jôßg}ªþ(‚ výªC#/Ÿ$d~Ø #3#/ÆÆ·]Ù—7]7l5Í’¿P¼BÑû\Æ(G‘»©?QÔù ÷"{¤_4z‡È“ÖMõþãÒ?ãgÀ±ƒ¸|D<_âÜÉ ãä䇤~¢CÆñõ˜0Þb5†¬ÝGrSê7¨Ñ!þ€?±¡ûþ{œ¤ú@:#gCøp] OèÝ>ƒ’‹Fè'‹Åü΄>]Ï»·û ûÙíõrÄ=o!¬êB2¾Ž6öªÌ×v94˜¸KƒD ’DdF³8ZÓH¹@l¦àÝT…±Žƒ¢@ÞéDÊ9ÿF†ŒÒ)`6”sy\vx[Á¤Íƒ–ÉÂzÒ!ŠsÄB\ÆmˆÚB^? ¼þã-èq2:ãõ88§Oç$6#Ù~ùøüBI •!Ñ€X>È´Ò’‚Å¿@í~“èÃó@z䔨˜" …­¨¶-HkhÛD˜ÔX™4Ì´V#7ØÍ/H%!‚)©»çW·„Ÿbl}&êp~(å<Ð}¾#/)Q”×­O7o¯Þ¼àÀØ6–*è{a©ÏÚ©ìBô™8eΆÚÑžÕpEýçj^ô=îGÙÎi×5|eñaK­=-ë+ýÜZÁQ¸ûlRTt¾'£eËÂI+¹¢%´qZñ1¬ïv…²ÕSÔea\Ì:m)B%ôÉó)ä}eã6ÚM”6V¡J„Ðj iOZQŠªºÕB3SŽÃ0ÍoF#9DmYÒÑM¸jâN2 ¡ˆK,zfdÎ2L¹Ãz5ŒÕƒÕl£áhͦ-ê ­òôŒf3®•mÉ¥ñM9ÂLñN“tDÜÉt8Å8§kâT8& v\4×Ktá¬mõ528SŠ¯iJ§9Æ׃LO‚"#7àÚSÜn(¹éáΖñV›ŽQxg…„-U!®\¼N®]™ñ·2E§vF6ÍLUlûÜó(œÃS ’ÍnºK¡[á“i™Çm£P´ô·˜ œ›Ôò‡›}9ß#72É&œj+¥–ÕÚø>ƒ5#9¤Ìù‡‰ Òœa]>ÆšÉca5µixzÎ_S‹°ýwMÞ¡üײv˜ùÙ]MðÀCúô¨–m±3p„  €Ò’:aˆ m¦@“(ebD`EשúÞÑ-¢÷ð¾Z˜m&BË2?ɱyÚùa¶³OɆúZ¥À¶D‰ºa½´¸–»5‚<«kR¦S1ð܉€ü8#/äJèë;ùüÿÎ÷öøô¯sÂ|ÁÜ4Ñ>î§À­‚à€Ù3*hnœy«†³¸ýl×’¿„džîÙݺøiÃl1ä c©ËŽ7G‰Õ+ý~&Šx³Lnš#9Ѽ¨xÀ¯QŽœ6‹lC0ü¯ éGàσ>Å sCðaÓ‘òÙœ¾FlÍK€IXªÿŽæ#9 ]†*P‰ànr`Λ3‹Ä_¦Ô@VöD¸Ѿ¾? ‡èRŸÝH#/2)#/B¬Pþ©íüþ¤Jð>˜þÁkK³öx—5HEöiÙ‰düÒ@',é±F¿W÷šÝeMÿ»ÁT’GofŽ#/ A1P UŸÜÖ§i"ñu(›I{vº¨‰’Mãt­¢*P–š’Ý*ì˜Õ/)U¹4Ú[¥´›(ØÔŠe,ÓRYL”­1K5 ¥")ou…,šÚz›³~×¹SiJ*bM¢¶³V¦‰ãŠ+#HA˜a(TGz–+!à i( AS*¬£-JkRU@jhÆ“*¿8Õ]mó9Ư‡vÉ5í.Š*¯p­j¤I0¶šÚUÊí¦Ñ¤Í³dÔ­™zó«Â•i´ÙE0ÔÕ…ª-–ËI½;mj)kÅ¢yÛtVl³Åyy;’R­v“BæY®¬Õ%x.²×ŠëSé­®$m¼&»µ-¶–T5p#9ëÞýÙ¼J#7»†0kp»'ÉÝÓ½¨ê'4Bá ^­ŸŸóü!õyÞž"}d‡I;Æ7B3×qy5$Ñ8e;túxÁq³„ȾÞ=šXŸuõÃñ\'Y#´º˜Ì߆îð4já4ÄD#7 ¼pëœI#/š« O~éš–›K ¦´l¹dD€A„{ø"hç›nž…Íd"6³JÙ¥mìª×M @Ö02F›‚Ézf  0…Z%¤hs»JJœGÈyc¥}Ž"§"•b¹#/ï(.C -,ÐB31-_v®ŠJMl¢Š’²L£-I”6ú vPÃe¨¬¬D´bQ”i¦É#946›e)¤KISFÃLÆ3)Š †Œ­”ScdÉ%‘¡cRV,XªR¨**SeJS&Mdµ2’© –HÚ”Cj6³i€Y#9RbÁI”˜M2M2T²¬ÛÕU‘#j)bfÔ™$Y«ZYV(Éb’"F #/†U•PØE3RA%"X*H‡‰#9&Ë#/$4 Ä¢¥ pÒÆð†J›2#@#HDZ Í+W*´‰­iRª&Y)'‰þ4y¨ðº4ËÔ?#/ïœIþÜsÒw—³ÃŽÐrRrÄëaZrÖqºBFs ¢#/‰ó¢€à=5¯mB}ï\bT'ïì.±ó:Œ ‘†*sïÄÎ#9ûÓK±î¼¸*Ó0ÿ•7LOÓ3>ü‹Û $uç÷°øã÷§FqgŠ)›ž3lK#û<;±®tÝ‹f€Íµ”1ç.Ž­¦†KÀ䥴”;¹T¥v˜—Uò¥¯r÷và9˜ÿ›`Õ‡¿Kìdz®PèSù#9À‹ /¨a!¼! p)ÌækHƘÁœœeÁ‚R›¯WyóÕ}*—ÒÚ¾½#¿qý#/ßT€¿ö _IÛ®{dwh||CÒ*ƒŸËËÚ~]Sß·(NÈ8Ç'É¡M5øQ“3?ŽIù¿‰ÅLLc1š B.Ý"[¾»Û 5äoMcиؘ¥Ó/0à¹`Ã;A&…#7Ô³D>”dŽ¾Eë7¹ø6*Þà7P -ߨ¿—Ù3·ß¿ÒÈ„¶vð ]ö¨*+ôâ}5Y/†eÂ2²üÛQ+!_s‰¿^§!¾`E’FvaU&•#7ú¢¤=MEFJ¯+’£bm¬áŒbz÷µ–Gl£pŒŸA‡=ŠÍâG­›,Kƒ}aBóƒÑƒ u!– êH…R^#n¾Å? †Êï‰eU… @òî#/#/dÛcUF#7·Ë*î»nCÔáìêßDA Ü1O9t ò°R¤´#b›ÃÛå/3­¤÷ÉPá=i‰?½ür[áâ|¨pE`){³ÐÚ‹±ÚtNÝLµLÒP4 ÌIx‰Žì‡9g|Èpm–Æ"u«*¬Q&æÛ5˜ïKÈHL dñg[;P <ÀÀ99SvÄI‹õs%B8åÅl^›Ð#7Bíõ%(¬Cck£èƒ‰<#/5ö÷ß™ˆq¼\çšPWz$?ƒ@ÿÊÿ8¶\´uÈ…‚Š#9ú«,ÂEµ¬7æîœQ‚ÆœÕE ‰°2S!Wîþwnì´Õu«Kº”ŠÁ-,ª#/ÎÛŽ:w“ ÞL7ÀÆ2 ©Hà÷„`ÍNŠ¢ïŠ‹\46$Ø#7H÷`±¬i#7¢œB4Ú¨$6ÑΡ‰¬á¢Æ,6U%…îËnR)«L¡#9­k4æ9µŒbP6ÒV£yŠÎjÄsBÅF[ªÃJUdQ®Ë¤“KV‡’EºèʦqP¤1.ˆt_×á,Ù@„¨ì#/YÚ'ÓÎ&º<¶Ã¥‡ÆˆþETéÍv8ØD§™šCsç´ ¨Ð93ݯ* Ød¡2Öã¤R4j’±Ì#9pyz$¶~†ðb=QáëgŠx”׫ëèk±—´ú“Ê`ï Îb*†[6&ò2ÁË•IÛѽ[™‚¶=Ã9Hußk-¥6P»H‹®ÎÙ§tTíìëìã·@ÿk±]Kìèç¢Ñ$} þoʆÀK@^‘J,å×úŒtïð~àm+Ãmm°ü¦ÕÈÔ·h`”Æ/îW‡äw}U¹%O 'kYŠ¨ikÕèqɹ$hXKÍ8B÷¨JŒM •ˆ‡q‹æk}QÌAÉÆ„ïJŽíkßi0n‡¥³¾ ©P!+]¾7‘ýû˜eõØçmÇëù=t{ø1æ€ö!1òCwõT…>9¯ °uN~\¨?®“ç$8Ÿš¤th:4L‚;Šð‡Œ¡ÉWùpÙÔ¹gÝæêMñ®<ȆfBcj$ì`°àÉ-”†ÖYÔ§ô™'$À½¾Ëå+`2k[Ô•ms¦¤(LxÜ¥†˜„i¤˜Ä@i©IIâ4{|÷Qƒ!±¸MÄŠ9ŒdÂ#/tżà-8·P¸0ëÓ:õz6a’22Ë·V 1Œi B¨h‹)àžMW"½·Œy˜¢ Óm§ð¦<ìOYB¸9“£çEÑ0jHL”âKÄ3ÔGQVµ:VK¡×JÒoßÖè£Õ~ø ª‚'aéÄ0ï•#9*—«(A(“Ë2®3>R=ö·Ü¦|Bˆ˜#7#/Ài `¸6Ay…½Sp«á(š&(šc5 2©2 ”"^1!XõgÓ÷vö¡ï;þιÊ{–èÐßÒ¢áuEäÇšpò t†‰B›™ì#H#9IôY\Ý“ˆ±5Ùã Î-'Û¤ ÅúwédK'74Lv.š! TÌÑôH#9CgÉ—® vqEá÷ñYâ”)µØ(ª;-­”]éÓNHÖ2c2!v½Pc+vÐÛ8Ø‘0ç@ì6] §7PÛ´<|°^•S^º)W'¨½E€xž§ îë7•³<• ;ÎèLÜó£¾wIÐ`¤NÐj#9¢È €á†… B`F!víÕëèz»0<"y:c*D1b`ÌqHT<ÏüY»„Um.™ZO«çsklá¶P̉K¨€úh¸„¼cO#/Ø(ih#/äl†ß&ãÆy‡Øøw”¡é#/ó(‰àv˜'=œ¤/¼$Lj¿sFCV±ŒÃd1¥¼¶pO¸œ’É\*9ÍYxº4c° ú]AÝïkÎ|;±œé3HžÀÒ+]S‡Ùu˜Í˜¦7¥S§½½|›ã\™÷κá5Œ{x5#AAsÃ*ãÁ>Îw"™*zaŽ°LnSËI†Ö6aª#9ñwW²¼kœÜSŽ…Ç™­Éf—<ó­‰áçgÃ×fm2ÅLH¢ ”’#7C8kX7 -‰ÕƽR7̆¤ÐÙÈ0²*¶Žýc`Ö5P!;£)òy›—ÐcŒ¯tî“ë߆µnŒ†°$÷ ON' g®Ó¹X@šÝihžXRºVv#/”X-èf#9ÕÉ`„#]ÚãY q¢¼o°wÊÛ298EI.£³ÔMÝúý úxb'ËÞÃwOßoàLÄcÕ‡¿å¡ðW®y‚B]eJ墉ÙäÏBC©Ë: ‡»]˜ `ŒPg½¢à꾎ãF¡x¨U¾dŠ²0û¿LJî¨U ñêúÔôlYÊòÓ Øl‰Ö6É'Ã1VŠ#X!ÂÈÑ‘šœeò²&(™X’'^¼ÛÖµëWY$É3tˆÉ#/q1i¡u±j¢««›ÛβñÔîÜRÛ—#CL`Êš£hjÊD«)H’ ÍuéåNðxŒ‡úˆ{å~£u;ýÝz.Èvò|­Ëú;|Gø¨€J<=^ñ‡MŠøýOw„ú*4ÙgT>uò<ÑCGž8fSžýs2¯ÌÊô¼kë8°Š™a ÂÀªN˜´AÃl›ì³^‡yfnN×ôÛBHwæK¢~3ÊÛxÔV¾#9šh¶!(Éi€%’ÆÄ–œÀŒ(Æ®‡3Y‹Qj5_xÕs5‰*Æõ5_QU{ãrQ59*C/ôEf¤ A€$6‘pÈ°¬&‹]M&öÁ0õ,û8Íi¼­¸­Äš‘ö›†b–MBRòš•¥u.N0a#/@I©;`É¡ cf‘FO½#7 Íg~03$ î44Q0A÷®ä´ƒÜvœŽç®ÙàŸ]a“ÍEýa<: b˜'„sˆ“¥Hê29r,Ì? Ê¢uU>œ LÖR¯µMÓbßA¼¡í: ôèî<½Ÿ&©?É™ dä¦JI.f HÌÓCC4©J#/ˆ)Ð;~ŽÛ=ãÈÜa©äÚ(€ëZãfòˆØž`×Éå<´9ëڣ瑄H¼é‚~î"qØAþÑ¿Ãoºû<_¤<ñÜÖ¤ôthmþõT–‚/Ì`U bx†°þœûI#7ö¨o´~Ÿ¿ýù„ „“b™·* §Àê7Dóý_qÙ¿ôðPtq$0þ¹:‚Ï“X.P<¾?óº.CÚwöw²1¬âQ „…*?Š!û;?xê " ˆ¡"ÔmR#7ùE‰<Ô1¹|ßÁÊ#9KÈÁ ˆ5”J‘ÕÀ3ÝÖM¿cBz¯‹Hðíà=Ôó…x(«Cšxy>29€¨¨:!eŸ81#9ã\ïg(:õ›:u $ˆ)èìfX}Üà_Ž#/h4&†~ ø"Ù79ÛªTª*X“ÛÞœö#/}¿ò¿ß=‹¸‡«ãÓÃøÉQJ iPõ’ŠYŠd¢& "Ä#/p 5#/ƒHA‡!{…ѦPMÊ%2¤iHZt’J(Ï“g,%õ:¶5™—ìCèãqƒ2WF…b‚ÓIbë¡^F`Ù õaìGCIÀõžtóŸ£Gè} ÿï!Ø>=U‡¶¿ó¤2v'Á>„ÃÈ<ó’¾w3öEˆïóUAJ”¡Ü8B~½¡|M }Ì–©-%"¸iyHtúvµuâ}V+r6ì"fRëê§åò¿zðaß%C fŠöU LÑ7o:Ñ” C‘@kÛ?ÌO˜iEmãã^¶à:Ã]É‘@Pw#7¡›cð.Ò ™ê %M4õéȇÕ<½Ö\?”ƒXÀ!ç Ž`X¾¡H.éÖïK´µñÚ¯ª#/ú_€çÛÍ~ˆ‹!BEi#7êEý-e‡ëfdt¡þgj†Œ3U ±QT*l×ôZò8D´Ðpë›$`£Ú9¸YHA¼ê /¢\ ÚQ±óó2ñýT–ÆûÁÆ ëÆ’Ι«ðÖêJ1°ÞàŽªñË;³Ž*I”UŠUµË1³’ajèÕ–a2¬é&k-®%ŒA¤veh1‰>4 Æ6‚Å&&:A±¤[U›Ê#71´61™Y+@F jF¡51ðãX×V]TÀÒE#Æ2@á&rÄ „¥h¦‘(s›ÕÂlÒEÎh0†#"ì–f¡7çŠm ð“$*i7K…°Y4a @´¤¤ß6ÕÓ£L j–Átr¢ŒÀ˜e¥¬ÊYm |Òë³»™ÛÃ#7²*ÅZ1‡F£Y©»µˆ›ÕZ ÅÖAÈ4vÈzøuW‚#äîéݹl\ÛFÒ»£F¢´W-ËݼO;’g®¼kÆñÏ]vßA±ƒ\ƒÈrÅÃ9Z›:È.Zv‰cXÑ2'Fu"ïþmfe„7ÉpÖ¬Lhïot4‰Ú%Ëá Û’5cŒMѨ‰…­mOëÈc4Ï7Œ¦Eã¨à¢¦õCT´‚! Ž“Z3Š×Nºï‡/ió(rH½CùÂz°P8ñýgmàéR_%øÒäƒhq‡¿²pŸˆ{úU,Mú'&`šubšÃ#7 “ƒ80#/IöÿÿÑŠc#75ÌØp…üÞ̾GŸŸà½’̇ÉÊäéè =oªësý$ûÞ’„¸ŠBŸ@<ôJ)˜J@HH'§ùêô+m;£Q¹z¶ñ\µä¹´ÔÍ$Ôšk–òi6íQ*$ÉrÝ&ª0±X¢è‰SV‘h)#/°3"ˆI$bIÝ0””cZs²ˆ„%¬¤&H…#9U`$a¤í0ŸÍ ýàâDs°öSº#9sOª EˆBn&ÍÐþ.!”&ÄZ`»Ò¡Ä´èé¼qG9²K* ,‡ÒO±PP @àè:Ï_‡Ò¼ü«p‰›ªÐ‰ª²êQ#9#/¯Ôª©› @²,˜|ö4ž»9º±y<ñTc=ï3¾ìNƒG‡Ñ=xVWJ›#´Q,¹nù:]µÈ†$€ÉÅïX‡÷1ý ›ß*dsûÆ‘@9áÖ27¯”?)ú<¤ïwØà>ÄÌ;ú»‘{#/÷"2‘ö®‹êÝ÷²ÛÆçWmÜRF”´¥!ZQþWìÖ¨42âr Ť-õÚÝrëÞk¨Ö"’)!$™ˆšÇo»cÌ{Op;ÏgŸé¡¦ˆR|X|ZËáÊûT‰J¸ `ñПwÍxEºŽjUgoä_³C)øIòØ=GÃ,­«¤ŸÇ#éÄ>Ä …ˆí§ø½¦*Ó t(¶w—i㵩ÍGÉá¹+´Ýo¾ª/ a˜p¨VøBA„:vÌÉOÅG6uI11¡“L­¢†ZÖ81†Úª’ƒCLGr`ö›Š>Ã@‘¢†…° ßlhr#9SBؼ@þ‡çó€ÄŸ+í='¯!Dƒ#9ª¤ŠÙ`ù$ ðŒ$˜üt6›Yñ=åß˧~Ú}?®uàÁ;l¶ÍÆ*¼·èÍoüY“2A´¡ÓµÈÓÎ6“TVX*jCuþÿÛØ"žž‡jIµ±Ô@çíVg€3¨é*äÙÍ1¶ÇŠÓ¬-'Åá°™dóÖ¬Ã'%pþcž€ÙM”Ñ gNäžµÜÛ0ÄfÍ÷Î+ÈÔœ á&ân8„ÅaËfÈÓŽüí˜áò*!_¹o=WçÜÊû`j; qe°ˆŒ07V´|Û;82¨áÿ°uüµÓÖåGý᱕uš”Ù¯(ƃ —ã*­Øíá®çÖQ­šÒþ‰Í­ŽÁ?ùCàý ÃlïèpPÑ÷}€9ïIÉ{À×Wd>$‚„ªJ¤´ÑÆ#l‰´š4•#4Æ+SjËRj‰j21”×ÝJèƒA¢eL”Ô³ð«lÓ+E&iŠfÍ*‘JZ¦™jQ66–Z›@D°2À@„$# #9È%¶6QÅMX"Œ²-Y¢iªUÕFØÁša"¦#/–àÐû¿k _¿Š+ý.?nÉßݺöF¸sH“˜ˆn«ÁôHxu0ˆ%TL $ 2iL T2W"ÕHi¨#9j—ó©;1B‘!ö:ïBOHùÏG!NðD;1ë ™dP›•Š).¥óí-{}2m°…ØBõ´H_EŸ´Íç•ß³æ´E.Œ°ÈfË!ј{ È 4|0}¸Áï™·AÔ“(ˆDyt;l“Á$ÉG—3gR›Iróˆ!íÝSã÷'ù^j ð(C €ž@ör>dó Õ?WnΘ‘ü`xÑ¢_D. r €Ú]ˆDÛX»$¤ßŠŸ23Þ-2™™“4MÜ#/èÈdß—Æzó(éËÙ½`Èg$.¯£¤5#à‹ißåS ª6Ô†Øܒɼ}ˆ€o8)S(`×ÄÁ¦µ¾kccCÖtfŸÕÁ! †¿ÂBÉØÄx9šè}›ëáõH¡ÞIë¾ÅÁ¨|ÈFy„£´9÷Wwj2fkPɼ>ѻއì#Åñõ(r{È{ÈrF€ÈC‡yc(;°MËåK#/¨òó¢˜èd((Ae#/¡BÒÀâ}»#7Sú¹º'ŒEkÔEi$4ØÑ$p¬I³ùׄkgW!U‚MŒ þ+øƒÏ×ð=k!…sDU>¨·ø˜ÈEÓj÷co³…7´ëZªøñôE>É>ž…4/(}F[Q°š{p‚w:ßîñ†¸8tá\XZƒË«ßßð¾_˜R[¢ÉXÒ©6)‘kie±¬h6…bA½ÿŽ¼8çÛù>ÅæÓͨ@'¼œÃF¸;ë…kàJKt‘Xþ“qŽS}ëà|`pÄLpuÒQÐÔj(È2´0dP0|~~&ž£=›ÖÁõ'#/ºY"Ã#9.e,¬C*LVúk¯Xõuåßy¼Ö Sø¼0¼S¾Öi ’|?Ñ14®`ƒÊ@¸äÙš04(ÁC3éÄâ†åuÈFšaS°$RFÚboËÏÛöbLU)Œyb`H‹­0rÐCd5¬JZÛ032í¡vJ!´Âñ ú˜„ `]ÅÆ ­Z{®-çS×/ÃP[2cóUhLºÁ!wúE)A8F4¤!¿ ¢`G#Ñ‚þ|¡œï#9oÙ­ž$áI&ø?4«Ër´óz H¼ëAŽÈñ•™Ï×¥ÏËҒĸMœuΘ›:o7#7®L­¤„³#9š¤Á¹xÅ0€> 4“©Õ8âTH”g¡P.6n/U‚•¸ÎB?˜ƒRøÜÕÜŽ’¬càÏxHà³E.F&ŒÄ œ%4$„h@(qðtw0ò÷¢.ükgIò|~Ü_5²'Gôýã€!ÃÑçàöCê÷{30¦€®cL@p$bµx¾“Q¯’¨ÏµÈ|KŽô½ú#®‘Xß!o<Ò„öôGÞ€> ÂgNû‡n³rá@THy{I“Q ¦{{öåµàÔ˜H¬›%^šäº ŒBÚŠ 3€ô#9ôqõé<±>$9ª ÷Jd†Ak2}s„®ŒÙÒP)èÐi¶xAjÂ'FA)H]çžPÛé:H³×v Çh#/‰£85CçãeEs\Hˆaï*…!( Ún"^—l ±7Év`Å.ΖŽ0`èØÖËø`ôDqM7DªT•®LƸ^dK5âT#7`dä@öx}ŒøN 6'àÖåZÖ² ú\–Á#/öÒ/¦ÈŒ‡_fiœhÑÑÌDi]Ü©er(Š¸rôô§¸[¬A½\@‘^©ªCÌÍ®˜?¹9¿cÅQÖ€á õiŒ5Ê®Î{ë9/¾½øÖ똊²V§.P$˜‰ZhË­d-§G¡Ð5]=‘#RÒ°~¹a$qX`ïÏQâÏÌþ]# »Ïl4îÉõàd ÐCžwjT¨œÓSFK8ZÁÚáS‰]3»XÂÝôji£>R i8sƒuç¸1“±ÌfY¥‰OË;ø¨Ð#4öû½*Ôí¬g¼ë7ȇbËÏ4¬š¡ËBòzj¿…[kœæñB!9a±òÎ ÓƒÀ·´ª(ºq… ½3ût…\¿îÿ#9q$|=_lYÊT:#7u AEP”’\â:&a& »#/E@#7ØpÀ’15.–;“c4’*A'¤ßpt+°ŸqñtÆ…>‚#/ÓçÀ‚‰Ûáó^ŸÁUCÎçovÆCÝêæiÇ2JHŸV~½ù'Ô6žrvúQ„'/A×Õó‡#/ñ…€H”h‰;C·iAá!åÖ ³ =9ä­‚jêÆÃi<ý·ÂCj”É­”Ú”ª”Òp@ó>ÈNpâðê?l>ϯ#/ìõúþnÑyöø͵úô=Ô~͘rFOª}_Ë®ñ÷€L4OÅ8ÁÕ‘)#/Â#×mz0À£"jÉ›®×Šï0œ5š(Yb8”J,#IªÒ%(Ä#ÒŒÍ1$ÉY&f(dfš3‚WM‚]HJXQ÷þ>È¢‚õ?Í„9sÎkt/PTƒØçia–Y¥~p¯“3_»ÉÙ5D¤G°•Õ»¶!ÄúÉëÆ‘F6c#6÷`Ðó¬#9X{GGîí#9nK½·‹´´„sEÂÓ.;NÒ®ºâA¦4©#9P2U+€A‹†`H)$j´£ Ìz`9Ã[–Ðffò•©'#7Zl–°€›€ˆ´”"ZKÞɶ$”á‰SfܨMj˜°+55Š-+(s!ËŒm<Š[ºaÑâÈfÙZ‰‘i»kf¤¼#9á¬m ûûV4©QZF!o—6¾1a ‹#9¡lA¥ÕŒ‡K¦GpNÆ{A>p…ÿ˜í°_Qà§{Ô+šQg]&‰ì3EXÇ‘OOÃlª¿Ð!(#”O£ÏKKœ¡lnçOñ,†ë—K(_£éNFÀ“°ö?û-÷w¤#…ű“5äö•åé›Å=Á@!ñʾ™04L•H‘#9Ñ0´´$JHJŸ{`hF& 0@¾-k#R Lœ“$#9B ÍzÏl·‚½ÐŒüâv¡g»£/ täëøg?‹Ì’ #/0æØÌŠÈ‘Øj„AÇ-C8e€Ø:á ‘#/¤\§ˆ¯©þsà™ù$‚öÁ¦-c–Öö›*©ý1ˆUéŸù-¶ªÃ18ÃCjêÒí6Í—9½ÓÚÃRz-o©šÜm0’odTaýN`˜Âø/ºClx éõ:7Ma½)ôLlœUqM±=ºèE:ñ óŽo†ø›í{&z³;Ì‘H¨Æ3Žºã˯@£]tc¼ù=³|D4HšC™Ô:pA.‚Û#9!̘4%a¶\¤©¿¢*Y˜-¢™h#9ï~E/Œ»ÛêÛçÌÚA!GþÙåžça»~Dpw£‘ÏoZ®Ã'X»y32b µ°…Ê`ðû#ùž‰Õ8ò=¬>Œx‹âCÔ»?Áö=à‡OÍöâXþ2'«K|RP¨ó!ó*ÿ †#/™ú»“´·¿³ËË1Ûw?#7³6|eM‡·Õ×í[CN­7tC°Õ‹,a -ÂhP‰=÷MB:¿U$¸ :àjÇ¢š:ƒ4ḹBKU±ãé9ïòÓñÉ+tâx§8êGè8‡i¼€Ùëùûu$€â§V(Oxˆ½Cñ±ù¨„ЂFu|á‚5k5š]H`D™X †C˜ä˜àÈk0 RÓˆ-ªÉ"#/´”3Œš!ÀqQèC%#7H@+" É$ ûÁ°mº©áá(† }ž^ä¥i¯QJ 1¨fé2·AœÑ—"¤Ã ‘Ã_J‹™6Ç®ø ¤ØxgÌïÜù¦æÎ1‰Öú}–‘ádjC‹˜®!`Ëú4x%àš† ¦9ö©7èÔŠ#7PP»TŸD…¤œ#7Ì&}’Øñ ØlKi œÔ#9Lp“P°:0³aÇ£ç`ÕLH¥ªl°Dc°g\ðþ¼Â¾D=i$?å€2†c7oê.p9g9a®}ì#7 ÐÛvoyÜpaÌ^H;ˆÏw}Yë;9Ä¢$ª¥òù¾:8#9»3Þy¾~ƒ-ÿ°ñ}”ŸDY#/5]°#7Ö~ž‹[¢õtBë–}䟅ÿwŽ#7¶ÚcCmcb'uJ4ƧXãIøg Çs`6皪S‹˜#/£À,(DE5Ôõ”@fEFPúàï—óþâÿOòoìäÏúqg9ñ©}q~I‹ëtÚÛd×JXOD‡ãðˆ±²î¹›éjK䢨‚#¶­±0¼aH~cYX,;B¬VÙ™šo_Ðõ¨:Ã#9G’6ÖMÀ„Äø#7éظ€q)‹z‹â ¯Ž'xm®è“B–çàÝ jd#9ªE³‚N»8ì;ñ ÏÍc$gŽ'’l¦Ž š)Ë-`u>žçÙläÝ«‘§,(ê4Tìú]ßíýþÍŸ¥¤’^ŒÛ…³,XÙ™sÓjÓˆkå~zƒ\mL\&™º ÓKðß^nD¹2$õ‡ˆY•Ê#/è#/¹ÛAc¢ïe×G^HG#PòäœÛ‰xpÆ´õ7’KóÜ݉(6ëÊcJ0èRR5ŒòÃu^Àð"žØv’'òèY}ÿ«Œ÷u×ç#/Ê¿ LB¾ˆA3á†DGÌxáæN'¿Ì§SœŠ›óôöl<<òMjQ2W"Ÿ#95 ùÉ2Uh¤ªŠ´r·-ÕF²c` ‰F•ˆiVh2Fš( Tìg±Ž=‡C’û¹ùa“Z¼¶0Ï8l‘-¡5¦F ŒÒÀÛŒla›a¤z¢RËïôõ;']»;{7nô{ v4î{˜ÑŽÉëϨàˆlÂ(¶a—×Ó`bƒøï’Œ·ô¹Ç<¡lëü'·ÚáÙL|#/={l×ÖÑæ<÷£)±’ CEniÐîÖ’ èæå'qBezCìÇÐî&`=Ò8[7öq;6̲Z2™€tNI#9É*»Öª– |Dö«=¾º1^èöâjd8â$C¤Q£–˜BÀñb_3+#/ÔqH‘²èÁN;(tØ!ÄYW›ÆiB´«þàB,¢ÄìuD5‡çäêµöLÎZzI6DT˜ÇSŠ Ž Î!¼1 $Hl«#9 ""µ¨;~‚‹=Cöÿ²šõÿã{Ñõ|Æ}5óxŸÕcס†!¬M"Üî»·«|h)FM­î­ve/¡Ÿ4úu˜^ùhé—Ç¢ë>}šö=&ÞGqaÊûÚž`Z©Ä©ŠŒŽîÈTʥȔläÏ$Zv¡B¶å#7Ùu>i¨ð법 8ö§ì »%¼(Àz$<Ó^jÕAè±Dè@Q<æá'‰±ÔÑŠëáåì<½à9ÕÔó{;Þ]{ ¥ÌúC1ÇçÄøÃÛ¬‡†#/0yÎ ZŸ,Ì)ø´­×­-ꢯZ)Òž9­§58¼¹g Ú#9”Éɳ#9 ›&.‡à†"íAI³`¾¸™oa„orLo¡•4ØW afXN™ÇCa NÌ9Øv”©I›b¡¢Ñ®ºèl­‘0&}ãÞ<¾¸„õ‚Ò8Í Å ¹·C—dÆ ˆÆF#7$!±Ñ`Ò‰Ð1GÁ¡Õ +Á‘§§h䚉&;éÐf& "@ ä"Q15¦"Y>ö#9$SZ#9Y§–”Bb»ìª¿5Ì‚8)ÀШRâ¨6Æ4†ÄšÌÌÀiê[F’vÃ%–!•=wI‘žnºÈ’·®¸¥"A ãv7ÈÉW›#9´B1Œ0˜œ&Û¤$j‚(R#/=j¢°˜0mƒYei³¡cˆÆño^Víš™”h6RÛ)©¡”ØÔbÔ’Si±2ÍSM#[)©wc£ȆÌÈÉr&©Ûmhgc …É,p5nA¶Ø¸Ú¶2$ ¨Ô4ãW¿µ×³Ù› ¦™¨ÆÊMȆ¶¦TÚlJPòÞh^ Ð0ÝgaXD˜Ô`ðÙx7•l@À5²¢ŒD$ÇmqéMºëÆ1¶V ø—N\ãZ¦÷i±Ž48!Œhä`kꪵŒ$X¶4ÇƵŽƒZÊ#/ú8ði<÷Tq“hlFèP&ähÓ%—(¼–ÁxbYf¾6UŒfâ–dÞn­‹Q¯UºQDŒu‘9HâG,QH£Ç«%4¨«m‚Ûw–Ê°)¡)*’ªEEË!h0Ì5Y±¾Ëƒ²—=' MÀŒ704Î#70”ºÀ˜2*b‡ÁlNÔ«2¼VAZ@c`1#7<Æ´°d‰3-$¬­z ŠÐQ¬%F³¢")"ÝT‚&0Ý·(C7íËœpˆÔaå!˜ÞC)°l¸a™šœ@ã6¨nìeqå+RÂA[h0˃yíµ±¸ÍYe‹çj<2W͘L*h™Åà¦`,a»ƒÕ`§6òs&ìáíL‡óÉÖ_{<Éí{tñöc¥t{ÐQ¨2¶ß3–Ó!_L‚Ë#9ÞÁ–hƽäCuÆ°xÃiˆ#7VF…Sa¾&—Qê±ñ²¬„Ħæõ’a×9U‹FÍ­Ñ#7f2*²Ë–*P¾ Ytq5‡A3‚â7Â&í¾Ï‡®rÖ¹føø8‘F·PES`~쀃 QìŒ{%8Hovä4ø¶ZÂÆPfP­»s7ä'qùG㧜°ÒÒpRˆ¨+JAƒL äi#7‰R^1¤)J F]è$ Ü@3d60(#9`a0КF$Di#9±¦x&é„U¡1áüì˜#/¹÷ž^ƒå}O£ªƒ'"ÏËSo«ð¦¶Ä±³£TŸ‚`MS¶ü#7êƒÛÕ#7_²" iû§JdF"ÓXßòš^‰“^ÚïÝb‹Õ§ìiFMŸÚÒÌJD?M-'¡Ël0€¨Ë6vÄ$i©ñôò‡“zÈ2ç¯#9Ìž¾)Ã×€ãÞÛM¼50š\)ex;¬‰Ø¶âêž¹/Q…7Rª&i!\ÞàôðÊ¥áR—ƒ#9ž[a.ý·­ÍRÛ÷½ø®aˆDBIaÍL#77´nÞSHBí®x6á&œRWº®±“­Ö¾f¯#7¨°7ˆ‚ÑMiÇ;´‘™¾C…ÑÖ«clXªà¼èpê?½t·ÉáÁ­ü=æ‡ ã§c%uL0¹,ß·†¡ ¢©ï}ðl ÿq à¸TÑ÷ƒw¹}”lzõêiÞ5öù(£/ÉÛž8J!cO„Ù10™=µ…«Äþh<™1êJõŘsb-óœ-Z4*Bt<îo–3Í•#¾8Ôò$â.&üô/Ûöùõ&ôqcg1óZ[†Üb˜«G]­òk#/ÿ8#ë$O“òÛüM°üHwĹà¸ÉKE KHE2pŸ>~ö&Š%E[‰1„ì. ;ˆâšAûÈ(#9@(DêèF>ÌQCHÐ.š‰lA‚|E!*´r6E"m!¡Úè´«#9u#/cå@€–®ñÑbÛ¼ë—M]¶Ü®jvæC—mxµðÍI±´™’R¦Üã»nîÕ‹K (IÊA5(h…Hœ”2B\5­!Ð ¤I€`‡£‡#7ˆX–%'ÏBïÁ‹hXŽ£a‘I}˜§3ß„ÖCº#9©À!V#(2ª$ÄbŽ2« š€#7gÉR‰°!(¯`Ε#˜˜)œ(JÔTY"`›©¢d¢#7¡dCI¬ä»zlp¤ã†Ý,UÒíY]kÙ´VÆ+Ô¦–6È¿'×*ŠT¢¬TÄÆSJ4UAciš*4j*¢ØÚÊZ 4m2ѲT–e4fL“jhʵ6Z@“KH¬†±#9| (L¤Š„;§Ë7T>Îúÿ#³¨;iª•J#/¨ˆ¥ /oÔytßóŸ6÷mâšG/'Cʆ›Ã¹¢dØÊÌÖIµÂ#9Ã_vçœT!¥ß!$¢DSꜘìvÒÔ2R¨|ó[êªÛ…U'Úêê F›ÖuEÓ»³®µÝ¢–¶æ*B£A¹&FJØ”*JŒN3#AM#/ÒšCK8}ú²Ž)Ù¾äÉnðPûL}ß&Eƒˆ)ºp í#„£ Ù0`*€F`í$yB!æ½vDum™I“’¡‰(‡hqî+0Xà˜vŸõÖéP!šEw¹M I#7LCÉaèv‚Ž‹¢.WÆ(côìåõGâðsãºû¥½¹,à¹>£1ûëÌ¢ Ÿ¥ä1›½RKQ£|´ ¹ûI-³1¿ ëË6àã²0¦f3Ÿ}–8ØÆ2»™&š„Ä#Ð~ HÍ’ƒ9S†Ê8„4Ã2[85Ñæ糶ê]§&d™9ÐÝ&ÌþN¹ØÑòðîÓ€ˆ³MªØp#9Ã.é# “c¶6‡È%oì¥C˜âp§vXB€A­æOÀ®’ìl¾n÷ãF„Ц-¥ä•aš1&2'Ì ¸í®FZM3-‡ÎÒËJÄ?9ášÑ¶<'gÚ—0á£ÁÕ-‘ÍX^ļ ÇRɆ‘.ïw½ã¡B _ç'u#9ņ—Я°|$1;m‡Á4‡'~vØ­íw¯Uí@QÚ¦ÉÊËg«Oåå…û³oFÆ)Ù5Mk¹ÝÑ—ÎY•4ô;žEï9a‡È‡à¡ûûô‡0ä)á)öÀ¬H­RÂôñ•%b#9Ÿñ0Q/#7±=p‹ÆhEعBŽˆ·°)X…#9PȈ"Ÿ9ŠÇ´¼ŸäÜ:×.H×Ø÷È¢D#7·ñÓ·!î#æ]gÛ£#7÷ÑFÛìE c+¬˜¶úÖ@R‹LÀ†`¹!è‘$´êš iÉ÷•JÍ¡„Õ±ˆ!½Ä†Å¡´ÈâÐ`hû^Í þ@Ð`—ˆ+°(öÑ#/«1SK ˜ÈÂÝ̬Öb™Ao¨rdˆ‰"dg!Ñ£ ¼ðÛam¢M Ò0A2Œ2§R÷͸m¦ÑL&i-¨ÅÀÅ@ËwK¾j\ÖN#¨LK{Pé·°„MPlÁ Ò®+§ÃHá¨uለÊ.XI¬@®Êž­ªFM$&ADrbñ¤SæÕœnÛâ´- ÄPI{Ç©¡Pß²þ>œïIP½u¼#/áGÇCÒ’èüOË=P©¤³ SŸqÀo•b±ŸFdͺhd7np¾E3i„š1ŒsÀnŽ\¶û:kÏh#7Dï;áç<#/ÒE@|HA•CÖj‰ª¨Š &D0#/B:ÿ-g«M€?Cð‡ohZ¾±oõÓ¦EÉûa°ÿG÷CæÈbˆÆ…чëgéµ?H×¼Ï#Ùþè#9"ó:Mt‹Å®:¸œlˆ,–2sOOŽûŸ†M>:Âœ}î#/3-3ƒõS#9`ÈžBÂ"ðù:΢,ƒв€à­—p¶\¼fI¨³m÷³±õQ41Uëé¬é`¼PÉ™u}ÑM²A@7´B¢Ih^j(ž£[6ά ßÜ“LÏ B½qñQ‡ÚÕ`ŽìŒ1¡1#7j‹ûx#7'óìfÈ’£k}#9("ìŠUCÐ¥b)Tˆ,+»æôí°±É1x§âè74#/Ú_Ô Ô…wx¹ðòéì¾/_×ë„¿¢rI r³Ÿ÷èšÔáœp½ËZHSXõ7¾gm+KõùŸØ@ùìkC˾`ïˆ*‡\Õ](Uݶ[«»«Å0`ªÖÂlû7Ü21% —% g½ãÓùêùq/ ìñŒq@$7-DÀØÀ˜Í}!§B=Çíê¿Ò,›pmkAf³4I…0êÊ’ë»Åä*%(ËÊæE-,‰dDl%J•¢ñmu–¤ÑbŠMŒ7#7ˆÂ\Û•Ënnãºo7—n:ë¨Ìs¦.Wwn‘W/ñäÛ¦Ëy<ͺ¹u\Öe‹Ýà*”1ZÅ0œÂiµJXÚëæÅt,›I¶ñݧ-wft×$jT»·AʺËe£hÑrÚ‹] ®A@˜@ ‡øôét@‹Úà#9iE>XööÂ{!ìDGÕÛðïS7•>õiÑàÄêö¶6…ˆ„ÀQ=l)¤tJ¢÷þ*žô@{‡Ëˆ€¿÷]÷Ј>—™<A؈;¢‡¶P…„Í1ù2b?0à?U^ºhà„ùñ {øú‰ôà¡û~®ôþXyÁ;Aô!¥Dÿh…^áÚ5™‚*Ôffm—Ë}J$JHBœ9m‚†J#/ú¡QjpPµ£#7ïû…8¤@eCKÓôx脪#9”„T5Iµ‹ke*Ô)heÆÁ Ù">³ì`^„ÂHR†%ÌwhÆMsn‘wvÔçw]NêL-˜®‰MA¢ ½ZsA±¦Ïx27¹’ɬ\KJx~?9¤Ø”ÞQÈp‚Ö È’bž•Ò“$ÍÄoul´Á.õ(F’(ðB0%NH…ô¦:6H‰#95ézU­æF£*8b8¤¼³¬.À\Â\”q˜"”H 87õ_ÅܼDàèi~H@¯3éòŠüÞ'ÜŒÞ ¦-&"D13+)„n}g÷?uÌúspæp…䌽Ê*ß ´²(É$³JTÖÙR›iµMµ•,$w(ùvð¸ä‚t7Gˆ%X0Å–’Rbd@¤¥<úWà|LrÐR{·ôˆxqÅ bɉH‰  ›©«JÔf´6f¶Í’‚ƒ~ÔOô$<¸uz¡å‡L^¢<ƒN¡OÍ(ô“¯êLùÏ``á$›@ QÏÛ›°@XšC"ò¹ÎïÑe§œ|@'äŒá!>âh )þe•1XðÚ¿³Î*›–VÉXº5s—ˆ‚¨" EL.Ý®RÖqÄ#7 T„û­K£HÓAÑò1´)"’ƒq8xÛ­púšé´ºD?ô ñ#/÷!àGÄòf½<À-%IgŽ0Xà?Å¡)`Ù*œ%h¤ƒÈÌÄ°Œ\p#a,¡•rEÓ‘È\()O>šz2LŠâ‘7$PÜòM+=÷Ñ/hqO<îæà”Ñó™H¢&×8}?šÞë š6º¡«,´‰4…&ÔºN3öCA¯Œ«æaµÇäê§AÆ/œg×¥½kK®`Ö¦»Ç‹³mä%“$ÇI#L+¬ÇƒQãS1¶ìŠ•ÐŒ¿ÓbÿŸÛ4´U¡£¿>MS9»7±©´3p––m.h¨[¥ÙƒW/ÄíäžÂrHè j{¸L§#cÐ?d ¶JH£`'è‡LI=ÖH—ðæªT{»õU;¨ŸÛ( !F ¥ó`ã#9«?=”‚4“íÈQò2ý§°$Оl7‘ï0oRÃœþ7½kD¤<“°ózçëÿí2tå×ÒüýŸÀ?Þ•©ëH#/AуHX*f>εöšÛ'k§Ó(<@æ?sü¤(@ýß|ðöxú(¾ëÓÍ»,1÷ö·NWJ”ýJˆª6Oví5ûè‚S]¸ððˆµDR>ðyª(MHH@ÎP6#9½c€e¤4J‚*;‹lP‹CuÀívýŽÓ…Ãx\¢3]ÏCuÞMû1rËUé#7Y½œÄ8óæUŽ³9m˜ÍR‹wfÅÍ3`ãâÂbÅh¦qw–l ©ðh)3>ˆá‰-1#/à*5ʆƊÙgã¨OçÊ{!ì ¡|ç]ÌÌ/VÇ{öþé30ä• G#/ÕlãV`|ïÈ„ömµ,‘nTÒNFëyƒ Ë8(æup{Ý›ã{B’–±½¨!Ì-Mƒç$ÃÃîÌì’8Xî¬Ê*„K«*%ø«‚P£ï‡kzþQóLPßp‹,Ú¶á+hBÞãœcCÔ»}Gö÷gLiËÜh$&IæN– ©6‚4údVBG.©FÈñ¶ë Æ2ÛCÉÔÁ˜ÃPÄô°ˆÑ›ÄciiDšMc¦—cè‡vC"Å9¤S>©}ª·K!£QãY˜#9„ ŒCmÖ6ˆË`3ZS¹Yå§k:SÍ/_äõ¤ó``òv¿-ܼó`k×_b`GÄ|0}¡¿âA³ÜöÉÂY^ÖéŠãǦ½ÛØS”#7@Ó5ÛˆãÏ´®Ä'Ûʱ„ã¦ï/*/áö#9$S5¾Z‚ÀQ ÒêÖD–¦ñ!»o¯ð¯Á°•'D dzì‰v3„6z\'ð˜³×û4©Æ[_º®š‡o¼N³èõŽHŽÃ6 cG±Í­šCH\6‡Â' R »î¡¾ö²ÄÀ¡™¸vËâ;f6Ѳ³° ®íˆI‘Å#9ÍëFPUt=â>J;æ/i0UhMrÐ$ÔÇ$=åö{}ùà<Æ —÷#/F–/SK² *ÐÃê'ÛPz§ [=4ÒÕ>ROD½ä{ΉÉ²Ž8˜„.ºâ¼žkk×dBafB4>Û?Ûñà£{hLÂÐG†8 „÷z÷„) @‹²DaØà]B>Ï»ÜØ5ÉÈ«iÉÂðwFG… ”?óQñªÿkàüShl¤pQÜÀý­kÛ8’[!dšÌßñ˜µk·çêåGƾÃÒe¶÷{(Õèr¤"M¶Ñ  Ä±¡°Æ‚»_·ƒ1­Ô[er¸înðøÎõÆÌn¿sôÕ$æg¶ß†ns1Ù0‰o4ô¯¨5³Û7׎8“FyV.…e²XÿaØbRCiDˆö+íHûôß\} ¿Ð+Áî!EJ ¤ZIRƒ·´Öl#/q!2}};t)g•zÙ_á#7êo@ C©äÈèëÍûƒí% åŸÐúCÍÁ#/>óàs‰¸_Pö?Yä‹#9¦lgËrû#/„“ò<»ä™ãß ÙæïÄ#7— T8‡îp < DA¥‘FP#/'lPvµm[³˜–÷8í\äQ¯ºÚ¹`DUÀÖƒ"“ÎJx Ú«òRD`¡µ ;èTUI¾?²¾î ]½ÇS v`#/êÄ QË`¿#/#&ôpêr%:3ɱf4~®ãÑï;´­BNÊíBqƒED§1ûï:®QS„J)&,P¡(HI“AI)€qwò6t¸x[ë!=Û¦; 5Ø$:‡ï@Óâ³;BØ’«B#/Æ1XH áq‹Zñçû_ÏîfVREì«ë)¤ HÚüG>»º´Õ}Ž =bü|;üÁ´!!@°])!Bœ‡Ìß|Zw¾¼Ù€oè„÷‡wø ò‡(Þl-²©¡Å_ºývdÎ1›«2”)ŸŽõ³žÍ©ðCqúìc_PŸð›ãm„Jœ€Õ¨‰Ã/U“Öɉˆí{ˆvþ»då\~ºÛæj9 =¥ÄHéxøÝÿWöç¾ø|#/”ŸêøÞž'9+\YhRB¼!ÇÇ8¨üQò/Í‹‡®•„œUA¤_‚l<4 ÀÊ4ÅàV1pãUuŸ%zLiIâbæ nº)ýÿÃ3±cÇ’:öò ÐS÷pä“ü<}û}_Û °±"1ýé‹1ä#/ui.–%õêï#7´]<Ôöqë,zoXʪqЄÄ:oÁ#/¼SÝTn¾~·Œ[5#/óóô-E‘äv\°¡I­Â„“WÙUñ[‡ »âoc,Ò: ƒKÙ¦nAàMÁŒ Ÿ³ËHñ6Tê—#/ìÞ§ÍÀçæ]dý{PCAdƒÔî4[òTÆÚÖÔLû[„êË\³äë¦i&3îäS2M£ (–‰ +Žz·ëÐxúDrø’C$!ÖÑ6XWÒCHk¦ª‚1³õeÑ$®°Îu %‰B!í…Ã:Ô&¯šIî=û~îò¼¸ Y€ŽIh²bÈ2C0¶L@bÖ¦Ù¬•¥•M¥@!H„“ëîíÐWÇ9¥H÷!êàù/%——´6wø¾ãÖ6°Á çˆpÇ5+@PÒ‡Û÷ö;mÛñj´ÅUD¡™FT‘fÍ›DÄÔE&!&4eˆÒ•#&ÄФȰ-AQÍB~Uìë{÷ê‚ž{ñ@Ý’ÅYÐO“'Ùšœ;èáñ×>Ùyp`ã7œãÇp¸Tèf.SaÂ!Lj#8XÔ¶cÈÄÈÃ1H‡æHL/Çv‰jãò?qŽŽ¥0Ž¼iæÿ‡N¢V÷Þ|ØT}œS†¼Z­èá‹áe®=U±û»±|ruMcÈÚé"0= Lm·†q3Òá~XlµÓIª©ÈCæêìÝí>TO ötÌW7®ØžŒÅÜZú°&þ0ý;å—#7@šøJSÏ;ä~߇v*ªO õLžD Dû?õ’›óS—)T•´Úä“”Íð°5Æ©$?D"É–ƒû'|!Ùíñ T¤Óå HÌýh hµ–Īdf©›%ÉÀ¤¥¶¡§DµÑ ¥#/P¦èÍøîªm¶f×.¢ÕË;­Èf¹j»]Ҍnj†ÍÍfŠÌUÆ@2†ŒÚlT¨™C¼B¤Â j˜R+ 2#/i#$¨`aŒHž#7 LÅ™ ëhÛ¨KR¬‘$Fô÷¥Tfi-¨Õ’Úfׅʨ Œ#!³$ M¹Yè~ü\è´»3(iˆ¾çP)„@ŠÒå¤p0œ¶º†Òáã[w²FäVxȪx0ǘ2aŠBh¹‹M­L+ö¿pËÔáS FVdÚc8tÖD3 pPQȆyÎODj¤³ä:ãk‚ÄMè¥qFFSV®*Š@ܤxšÚF“iäU‚õ5³fŠ‹gÄ,h+H€ÈÒ1¡¤#/î›z¬Ç¤^qØ’xï6ÝÍ”]vÞ1/SÉ"$:yí¨ÓÊTT’iB A?yy)¦…Q EA4m‚,³Ávfµ­2ÓˆpŒfÙ¦†‚j#9>$ó‘®#7^’·Ï¡†ÕG*16m\œ„_K­7¸–08}09RÚ‡?^Íw#ZŽ#/M¢.cP,Ð1òƧ†2¸Ow¢L:œšÆ((­–ÁLˆšc<¤âÅÒå‡]Ähi¸&œTÅ]Ì1"¡˜èlhÜÄÁ#Ih6(@ ŒK˜ `…#9@è…Ù\SDc¬­ˆBS€Ãƒ¶«NÄ)HpPw\pý)Í$LGõv‡›½¢3(ɤÍY–Tæc¨¿‹Y£ 5FM®õÕÒ߇×ÕÈîÉ’³™Äzˆ0„S#9ªÒT!,¤ÉD11 ôþÑ¢…¥#7”Cõ©LSùTÝ{þ3~#9‡ n‚ðå†Þïáîò' Dd\‘¡`üp€û µ#/6ôÝGñ—tÌ7ãN#7Zq}pçå¬Î&ÂöñT¢D#9 Jƒ$ÊÂGµ%#7t嶇ÏR}bdà{sãdxmLJףªYPRÕ±†#Kö%öIÞLvïv”Ipq˜×všH=¸ ŽÂ²A©?¸Å—¹–.îˆÑZêím½µåÐjÌÆ4#9G‹˜h’8Pm£jGkPæRã`÷4H¢å¦Â4À|÷©eÂX@­MÍwf,Ù(eï”)SD#7u’¿¸ã5&ýîâê„Ä‹#7€ô™‘‹cìï%p—9ÑöÙ®¼·*Üì tR`6ø¼ævRc’p‘dY³ÈÕÇ~Ñ ý-vbŦ/Šµ‘³–ÙÆÌa2àÞvO¦þÍ¡_0„8ß"|ä‡èk !u@£îóפ<Ñ@w‡Yøœz*æZü2VJlŠõ=¼ôäœåþxå: §?Ý#/— Np¦QÀþ^=gµ÷î,•KïÀ²ñtM0†U‘(ƒ­}ߌSå=‘û~¿·èŸQ}æŒgt]};?À¸aÀõZEü=ŸtùÎ1 ‡¡²¯¯‡²qÃåp˜Úfib›ÆýpP¢ý%Xý{ë'³ã´uà¥åâò_¦o<1!ñLDfü¾07Tò¨rEL„ !^¿Ê€hìð‡±L@Ï4&NË ÂOZkš±Vdé …äóÓ—Oi€w¤Ls‰9Öü'#9Ó•J€³·ò,'·{1éÇ]" BáÔ°xaâqcCÊ×} Kàb”TYûö¯®µb8UœFÉ|Ò-sù™V…Í#êoN#7‰3 Ãv%i‚áêHÃ#9×hŸ£Yäoƒs¤NGX&l6 H²E’qÛoù àWdlk¼BƒaY£1r”ÿ>ƒPЛ–JÒ1 Ðï"ãD¹˜#/Õ)’²Ø±Êånš¬mt­Ö6æÒ[\¶Kræ«rÓ»Ù®EF¬›FÑŒQQ\¼ZÌF„?„—Q´›ÁÔñ<m¶ƒ¿\Fl¦fü©0ŽYžÙí4ˬ‡Ñþ¡ñ8¶•àK£Ž#²”„Û*‚áÐùåUÓ¾ó'äà”8bnÃÝëîïÌñúÿO'â:âø½™„€}òùÕ_¤ óˆ‡Ä#/?˜•)Ñ~ªÿd’ÑùÝ^@ÁCIÍ"€U`»]–šS#9FAÆHO>´4¾ˆMfVQ–9éfÀ^ÓpÏ·VÂ2³#9žäÄÐh‚nÀ(СH 1"jU0‰j„€"OOpÔ›;*¼DÙØCgÈÉ|$•ôC´²%²F‹UImd¶+ «ÚI•VR͵ ”(ÿt÷Ÿr&‚ä¢<ÂA?ê Hû$zuý² ú¤}õÕŸó5À*?ÌMB¤r¾ /®0aÌÅ·s#]¾láGkY õx€ú BTÅñU@z"ûx6ÿ¤ö¯õ#/% C$‰ *»æ;«®/g='£‰Ÿ~Py`ù“ q`>hPì‘h(F$‚#/á&?"¥Õkö4³TÌÙ$”¡ƒc–HËF“bÍ#7©(ÚŠ”¤É)%bš©¢…#9Ah)T! I!) „”¤…¥"@$uò¬ú+®Fä‚ c`ëY“0¨#ã­+‘"=Ãc6›M°*Ï.œéÔνNMé¯3׎ºª±`\j<¢ˆJˆ•I]M3 V:BLbm8Æ2" %d%U„ˆ(UƒÑ¼†û‰!„ŒÌá(Ø8#9H†B"*¹é7R0Û‚ŠR"ä3 ø¶Dwöbš˜ PÆ`Ì$™˜–c4eX…òÁƒ´8f2.¤ #/•dˆ]ã’š„g00õߤPÚÈ-Ñ_nŽÓpˆfíÓø/UIêËæòuú={û3†ŸO#9(Ì2¯>‘š”HøgoódÊ´YñNëð\(#9aM¶~§W_«­Ë–-õ‹Ë[4ª‘C:=Ê%ˆ`Fá~bTB!ªp~8©‹„J± z&Rd"Ê)4N¤r žfµ`ä;‹ßú·t})àž¥=€>}XТw5Ó×ÞnÝ5ÚMå—R¥30ö•Þ«W5ª6­j)r-\]uê·›y"y'ºfZ$Ð}¥>AŸá‹“×Ê÷"„(ÅLb©žIüzë¦7fÉD)(û¿f÷­æȼ ð—2ƒîP­Â[FîI…k£õ £öï1½¿#7#9Ö“6–iÖ*;gðŠëúTk¼\Ô _Œ› ,h½ÏùVZó“J7Šé“©ay{ÖŃ@1LŒd­[ƒ:wï´6W"jÎýsW¾.D:ÙÇix‡‡â2.Ï|&Ž-Á¹Bg‰srªqŒ>ŽŸîÒÎÇ®ÝC=J ob"A€; æ‚X–다£0É}1„ͯ2õ.äòŽTO—³ŒFÉ°×2©à.*âw[Û=ö •:Î0ÜÕé€tW¬Í4¢Øñƒ§Ÿ=ðÌÙ`ëÁò5†Ûݱ“F1x1l×È©èÙÇ\í®™ ´á¼»ž£=µ\Ê­Jæ8xÑsÃù*è`f‚pÑÁÕŠv–P4’8œ9vÒžÛ=²è5³ò™B÷û⺹á;¶in‰âwÆÍ"Tyß‚ãÐi1ŽÁŸ,×[é$žÄ§KU=|_Z¼5'¦ä)$$ÇŽ{ËpÙg9À£d‘9PouÍ„ýͪëÞ!s.µ#í{J:˜3}wÌ¡’A ÷HozJŠ7ãÂKp¿$ —/P…çÇßÔ¦®v÷Ïs§1…ߣôT«9c¥ã–H0Õu(ûXj~ví¤‘ˆ‰!A#9p(!Ûmˆ¸jå¼SvD–±àbJ—…´àÚG뎰øÆe™[³Ë·Ró• Âæå÷qÃ-žÑ0Ë÷õíÓ¦q»¤„Rj>iØ4Ó×2Sèv½°p:mÞYÁ¼ÌŒ †c{ÙoÞsÁâ³Ä¹´kjÉñN#9î/¤ÐR9Æû[ÃF-šÆL$ƒ¢fb3¶üH×ŵáé­öDä}½þ»1Bdk˜’ÍgG jU'·4`F³Vª±*©/€O™æw*«70µœ»@“׆øQAÐ"Ç#7i‰¦r0“¸ƒɵ3Äèl³Øßs|lÙÅ–®T›f0ªv©± ŠÑÄâV\³C',ê½\ ]xàH ÉãNR™¾‡}¸¶Ekj‹Zˆ§fÞÞ3¯ ‹ XJGu´IÙ³¸Ç:Øm¼Ga¶RÒÂbP#/‡i&½ftæ§cO†Ðò´á!± wæN¬†ðI À2v¸Á· õ£¦ÐtÄ„o+œ°Ù¤’S";ÓK€ê×WæÈ~Ù.r#7PÐt‡ºž<”o–|­ˆO—vØØbÉ"êÅ,ž|¶´¤ :woÞ%¶‹ÍÃõwÞáy(©âX” Óf„·Ó¥Y­D“#›á÷—1n`C‰Ó4.8zØ{†R±¯«µ‘OEˆ¢;2Ѻ?«X×~¼µvnƒ V½{zbnùqš¸Û~iÇBZLõXñsÁÖc]»Ë..éuÛ¶™º+sƒ4à]x¹n<Žd`%RÀ©¼WË>;Äh…ÉpÕq€T£—%VíÎ&5Sx»šâ¼%ÒÞ3—Ͷ ˜‡ñ/Áç^4l.î¸ywê§ÉÃh3q xÈï[x97”╬J#/Á‚±RÌÕÑz ‰û‘}82¹!`ÂõNðíV¨WädE4{ô|Oo¶SB‘)Ò$-05bZhXÁUõšé´ôqv‚¨‡B–ôŒ«m…ꌳ¡ãžR†«Ñdn/Y 6wŒàN,Eƒ—$Ì*X+¶Ôܲ².pR¬ðný#7G8?3¶¼+¢ŽÑß³… Èø&jB­9GÛ¼gûØr;Ó\ïäz9@ó;ö .OA›r„;M!ŒçETÃñ=#x¸;„"\'žj›«o 7Ê ˜<†~évÜ#/W£\F3ŒÕj<Æ=;–ʧ˜²®ñP¨jmÉGRÚ{8™Òr,÷Ò­&ÛžA]F 1C‚¤x£jx:¦‚‹KÀ#9+8‰!]`§ˆŒÅ’r¨öF®‡EwÄïÃÀêh#7˜;‚d`“ÂX#7Wû05€nb@>#kZ®·&@’d@‰r ¯`#/5 Yé¾<å%ÜoVffE.)ó-äB hAvc~&Ïè÷rf÷ãø•†úȼô#7#9#73¨ôê!tÛV9RÚ!X"ŠuhdF±ôøJ#7¡ï{#¶}ŽžDÑ ˆ,0ž<~ô“м°5ð>Цm$RªI*«ôfâ9èW8LMÅ2 _Ò#/ô†´‘<Þ/ž bhøIÁâv‡•±ÝÕúœç™‘±6kïœ+¯®ß\—• lF"BÌ=»Æf·X8E²zÔûìÑ›N£¶”fV’´l¶%͆5B8Ð7 %O1¡c#xÔ˜µx«ÆòNíȵ‹Åק$É#7J©©C C×o#©#/‰FTv(ÈÉÂ#7³XB™”‹"(ÚŽ^à´Úk@ÔX¨™APcJ*"‰…EK’¤Œ¤;B]I×^ìÆÚûΉ8Ë"£S#/98ÛÛ¸Îø6Ukƒ^F|íD¥DS=Ï"š~Y…&ÐjCPdK@2¨§Â¥ Q2TJU#/Úr#/ÜÑFµ|U™lðùôtÜÿÉÊÒÖ¹>øf¾Ë¬xå²ÔÊ#9RñÌUŒc–(Vê É®_;Q Áîa¶¶Ûy•ÌÃ7Z1Ò tlÅ¢Ev`ÊâdŒÒ©>,ÞAFΙ§1#9³ÄðÖ:¸ªQ#9]xZòh%Š3RC1WA”‡ ¥PDiòãOR;Æ]ÓxÖa%‚ŠvºƒY"³aff‘5³(¢#9ÓZ`²2™-,jH¥„»¨¬lM4Ç„$ä±¢·ƒ–Š‰OéyŒêœ¸øÜ<#mŽw4Þ¹m5+‰Z3x#¢Ù7T€±bF4¸HÔxb1Û¹pb™©[Œ,MÀ(Çcuìeé©M2´u㬳{‘šš(ÓD$5k›ZÖ©nË$ëa­Xõ:âç5l­ðÉ‚6Ć61BkŠ‚ãšÕBÀEšfU‹‚™0ÄÛPjÍ+m†I%¯Ë|kSžrvmØÄ ‚ÒŒceëVðØ©#7PPˆÁ {«Q*Aj$ÇcLhÇ»*ë¡¡ŒxÉl@² (ÑdmÖBæ¤KÀmeS\Êùf•“%+XIw­Ü&]JŠû ŽR‰bÕ7·lUñ¢·°ã…˜æ%"`œNÂ6ÍXk¾i§<]u@1r&©Hí›iF¶0E¡àgúy€÷®šzÒljq^Ts–¥ÕkHÐÓ8:!’±Æ£P‹hÜ2”‚¥#9°È4n%48´†“M¦&¡qqhÛÍÅ·“%•Fë·§; ÚØM˧΂Ö¡²*TVº¼Äs¸Šµ²UÊÑ"Œ0Ê5C7cWmÝF?'Æj¤èB) lSIÿæ9--¶Cáµ+#JB#9š#©ªŸ–FÙb„$¼*6aáF”ȦšHHÓÉ„J‹Ó‚nÐÛô}9È5Zœ„:ä‘ÌXÜ(Ê(-‹-´C!†Øa)2,™É[ ÆrU<ôLÎ-ª#9fæ`éÞQ¬UŽÔÁ®% JpÎZ‘JkLM0 „m’I» &9¢#9+oîíOß½{AXGÒ¼ÃFPGÐP(ÄXģ܋F:Ý”pf ®{Ábiõb7°'–S§m6`ŸƒØùÕ⇑[+à71m»:k])*íSH” ¨TdƒJˆaˆ(Ò2#/„ˆI~7 =ÿß‚œ'Ä#âHü_ÉÙžÌú}y¶ßo‰úŠ’†Š#9SI6ÃS*Û#91´2c˜Å‘5¤¡j™V(RضJ‚­b’Š¢JÉF…l¨Ø£Í¡M6I¥&ÉJ6R’TF†4´Eˆ”‰hÉ#9f‹)¤R©£ I0Û 6a”¢"bJ¢©E?[áê=œü'ô|Gž7! å¹ö‡‰÷Iæbiò9ÀÜ“îIF|îwô½íÓ¸ýWÎß“¨½œ¸À~Ï0+øÏ+ÆO¢ÉPOC¬ÅóS˜%±2ÿ0ò‡Ô@ο#7tÛ¦v®Ï~ŒH;£uuˆ¨m°5¢ãÌ#/š€å„Ÿi)Ñç0!®¢ 6ØT-ví*1v#7¡3% ¤i%ŸÙZ“'ËrL>OË'ì‹×ׇyoCCü³Q¡ðª ±BJ*¹vöð5âS=§ŸOQ&&Ó#/MŠ7{{ƒ–TÄ!àp»ò?†¤ŸŽþG9ßêbªeT‡zȼSü5kñ9Â,ÂiñœT„=+ü€};Vúkh­E&Õ&ÑjÄZ’Û}Š­rÚTjP¤ÔhŬF}+µs6²Á13úO¦_¬ÝAǃó‡8m.òdQ &#˜©>ÿvíhßMH<™¿‰q6õÀcXb#ÈT#Pï¸iÓâŸ~®ÍV4Cââêñ¨ºÔQÁ’±MI¤ÄEÛ0rDØ0mǦ”Ô\±#7A¼ê@¤NͶ`к‡e„5¿¦Ma<#Fc…DF6I¾±¼ÍRšìßt×ÂW¢“z\ÑŒLbŒ¿<o[¢Žl¸<1„·wy†PÄŠÒP£‚&FTº¤“¾p<è妚O#ãA¨Ò}N)H}lK»Cv,¢9j±2#/—Ž$J3V6ùÝ‘I˜šæ×7É85öàr[>Ù±âýYÍÈÅ4æ6‹,w|Žº8º!á#9xÛ´L[D{àà>Bn‡{²´ Ðß3#9xI¬ÂŠ‡O#/0é‚K»À¶#/ð<6ù¤ª©à çeT6ù»ó¶·Å9rMÂqLïâì)«à±H­Bû{4³fþ»â½ùÅ/R=ˆ*ƒø$s>í>3~´É>;Må›h|‰"h×êßoϸ¹›%îê·A}¾³Û#/ rr‡=A7¢ÌÁçÛ± Øg‘ÊIOq”.VF“pŒ3ʤ—u¸†»æqMýÇ#9¾Ù#/û:s+‰¨É5 {]Š›ìbyþ—Ã1Yøöß‹•EðÖÍL•TR¥›k×P¾óÆé §¬ùKÛN”À@–dŒ Ü':×€ZSø妪𠇈̵Šú}\‰fÓüÉ"º×w,úRu8V…„!ÕCˆEŠŠ¬ãôQÉ8Q10QÂrÂve° ±Ò‰EÚœˆKŽ€#F ¢cÐ2`(Piâ6$8È'»Óþpð‡…àhãð>Ê„(¯ š<ºO`¢À$Y=Æ'ŽüL“Ž{;GÛ}þµØù}ëÒN!!Ä ¶„üŽ˜ sùÈYdö•Q*…Než]{â9¿é/ñ¬£gÈ°äyÞ~³yíÀGÄ‚ØǸ†4Ëê?6fcÆï#œjǦ#AÈ唂n"дÿ„ÄœòFlf/ÃÇô¡b>æ Ú/£‰A~?å)RP¬D•Q¹¿ÐÝƹñˆz…Šù¿Ã‹[0pm´ö¼%0±íöü•¶ÕuŠ„3d÷¨'åñtŠÆæ³#/K®š,0!’c­ÙS]ߊ#/ó<Ùâæ¾ÆNÓPa=[§´úèsíõðX¤s{#9*ËQü¢Ÿdôýø?ÏÀ[ùîßÓZhÉNcD¢®ÒãÏ)Jñ¬Í)„ 9¢^7'Q®&¤|n=Â3—Ñ”È75#8yx|Ô®ÂI¸tܤ±%¿õ?ìW–¡«dïËèX£‚GSÈ“K’ñOPNÕ>ªt³Žu3Êv·::u0QÝ#7æé¥#7,¨71•Hë²í¶2X8 ‰¼ë´ã§R:˜/útÁTºœ#9õÔI£ž§UrîJÞÌo!†nYUhm2–L£J#/D¦vž0rŽ'ndî Bö­¼¼í›ÑH88$µ–B ƒm¡§zža†ÀŒä£y¡03Ú!¸@­£(qP#7ÃîãQ§çRIqîàì2wvèÒ¥ñ;oMBZ@õ99b\ȘœuZž†ìæÈÔ'm&&w ¤‰P2Ë»`é¡pãÙòFxq#725Tñʼn©ÌõŸ¤Ü6)#7”Œ–c|é£ N§LnfP&ÙÄÀ«H¬MˆÊGמxápsÀrf’‰ Ö¨Ñ˜XÛLîÖîRä„Ëd¤…NáHÝ.wKÇÄÜå¶,@E Í#/ük%w©ã&Ù§M8ˆÜ+Ba‡CËxaîbκÞã cfJm1{Aƒ(ŠõŸ?(3¶3¾ëp~wëƒ$^ŽÒ3ôÍöhÉ´nøƒ.å2"ØÖà,«­@¦`–’*&P'Ê£/+ºæ¶ßYý?ö‰Ùqž"[:æê©Ýºç’¥38ºä|e‡—ž¶ß¨ôfVIñîÆü’ÁÈM¸.Ñ]pݚؔ¬¨Ã0¯‚æh7áÂ#9ÅàÁr¹§h£ˆQˆj0‡4ï‹žo¬ ÐK@dpcitÎ ¥*q N]qG„'Ì#7Qo4T0DS)ˆ!!1RMj%©,Ü)ÄEµ†"rŠÂµŠ·š;b ¢`î5¦ãÁš„ÉÖì± ‰ö¹VÄÒ<Š–2 cj¦"tÀTœ4XãDaó‘É#9q׫ÚÁ•X±Æ¬Œ1•eÎ ¬ª#Yg˜™LÂ}á³Ng!d0„AÉ–º’“´… ™'Va´gV%´ð*ˆ'*oMšë†õÄF¢í3m&X ݶÛi`¦.G©"„žj`Ãó¬`±F¥¥%—Öí,•FŒÓ™Á ü¶À`Ú]öYš\“Ã#cÆò‹ÚCI¥=ðãC6@Oo]6.[d¤ìÙɈm¶*é¥Ü¡‘Šg0Ú›LêiÔâ “;Kܺ{Õ—[9ˆ[m0Zyk.eŠF«—Vë½Y0ÈI±Ýß6&|ËáÓ¸„æãÌÃEñ]fÅÂÉ]¢¶·…¾*XªwŒˆylÅ“-.æÊrë‹„ Vs™V¹›ÀtrYÌÃ:JRhÀÂ牉©Û>PÒŒ!Zô‰S7ĵ #9º8òèyÄÒ黆ºnéõÅˬEÌ›¤šDô&¥Á‡~“© Ð9„5eâœ|¹|ªUš­‹²Ö3#¨j :g:„ 2%§@l7 kᚨ‡"ß‘kkÌ›%ÌF™®b;îÐÍRX#¢ìî\üW\åì"5=Hé4#9Íf(Q´pÌHÛ¦lšÈÐÛ™éÀé­^]04©v\ζ–€sŽ°î`äXë@u½¡ºwËȵ"¡·BŒ5ÞÓ!>ç‡Äj4l\ð ¼L–³¦lŠ*ÙÀ#7!äÂfêÂݘCƒq£H±:Æ43±yP‘LPAŒUKËd39O48x†D̨*†Á#7LN;³;!΄Šóy¶Ý“œsŠÈû—A×qÇaàÊÜÏ9 11¶HŠÃOeÀ×j™£3XýÝßc\a9³Ï7–ë\öÖL^ C³J©a°C#%Ô÷ÀØåÓ$ÅÚæ[A h¸ÐÅùpwѶ7\¶\ê.ænÑ~Ãð„eí²æ\M‡\Ññט>ï-Ž]sæñ$ $9MŽîx/mä:þO—Xx맑-ôãÄAYôÔ–›PúbSÞ²‰—léä–y[,§qéÙ:˲^‚0¥Þ_–Ë IŠdÕ³†m£y²ÄÈèlk."ʸL\2o‡H<¸kä33°lÒüÔš´œL€tÂÉ“Ó-±QðÕÀ™å1ÌÇLŽ@àTºÁÕ¬w4q#q°#7•Õ3Ù¬šOtaQS‡`pØêÉ]:óß%˜’‰1z–Ë·U*Ói"qãc’—kPÍ dgŽ$4Ë8'3Sð˜pd€¡$ÌSÂ*‹± hQ‹LF»÷ß'#7x‘]¹ÐÉd4·=˜LMµM4+oLC[|*d#9¹‚^ ÊÙÅ»©·™¨C§‹Úݘ>Œ&‰MNNpŽž,Ï Œ{‹Â9U8L™ûs=Ÿ¶ø 2Ñ2Ú–vA=3±8LÉ$é†wqèÉWjîݒ➤ì]æ¤*Å5iÊí3"¼¶Òýœ¸/“SQI™’æµÛi¾\Í&>2Ú(‘â['s¸÷{÷1æ¥0Ð<Ðq#“°Æ‘z°)Ç7„LC·b0gaÄ‘SZü$Žd‘A¶¢„H÷°Ì‘Á Q†’®*”5Md×À#98î† òuº%=ìÑ5M@ÎÚÀ£x4*ùð’É Ã'WˆwF™ânuî.‰G”`èpƒ‘\Û20Ž>suá ²IÀtN‚x!0¼ä¼“L<^‡#/祌V1#7„-ŠSWHiº ¬ÅY.“©Ð9HE±»¼ÕDg#/%ÑfN%([vÞ&ãaeHC!2 J¸F+.8i:ÚБÕW® Œˆ6"¨&šìƒdGfAò3bà‹‘TìlÌi4ÞÈ‚‰‚è”7ÛÁVFHF¬-"«–Û94 ³‘v Äa‚êM:šDî©eZ«¢È¡‡#užd˭—eu&$ÂÐÎ0m Ä )¢*;ÂóÇNî<¸› # 1å5ØN0‡YŒ1C™Ø"ášQ(Á4d0†4¡#7t¯^õ~IQQ²VKo±KCËχ@ùö6±ÑªQEDJ•@1¯M^;B ¼9mïñ_‘,4ÓO¡@0$ÇÈ: ¬I®¤ê ¨@OPýœ>qÉVz#/ˆ8#.u{r(\@ÔCk2‚½QèÈ“j,Îù0ù›álJ7#9Ô™0K4£Xré̲ö7–Ç…D[D¤Å4s#ºèTœ[k®Ï½´ázaº–ˆQ#7O.Ò0#7¸[³I¾Lè àsû“N}¾¯: =3bÃ1ùu„¿²킃Œ›< Lùñ ¾»ê;û߬û”óžm:,4­NìoÆ3ÒÑ Â?­€r¸ôšw_.#/y‚Q>•C”ó°³1ZóƃX0ņE˜ØN1#9sò;]™›F¨Lâ]dm°Á¬O0••‹"¶•5w­"]ç<]Ûo,Ì‚cŒ—§z:îµÝzî–ówhFõ+†Âän0á …”´¥¶ÛHFešÙÀÙTv1tBPè0‡ Ó!2‹ƒ»ŠÀaÈý8œU`=ÐΞ©Là½%8*+Zð¼aj¨š´.ÙÍç<öp*šf™xF‹b‰s¡@ÙÁÂ@ÖC5BÀ>á(%hDêü<¼ßIõú½Áù.¾ÆµÆ÷çÓµû€_7–8ë#7Ÿ+Lgä¾QëpŒ¥ŠÈt6-Ê5Vš"t@lÈ4:HñÓ0´±\hh¬Jì‘1 ”¼4ðÞ‚¡¬BD˜Nã ߟˆˆgáç  žcù¡NÖx£Ý¨Œ›Úú¹NNg²ƒ½«9öCFŽª‰£*©ëSUyæBþ÷øÈp#7=|=dР~!CÚNk±F nË *q^RjqÆš‘ÝÙrõ'ÏF£UÂSL†FöóíwµáOºqÝyv2󷓘z4Hx":Å㊨}_0ãçüýydöIÊ#9!éAÈôìv#/ì:ò€Îê$äØÃCD~¥™?+&PâMøã £Ÿ¤ÚA”-kméŒlȳq…©g>;è¦Ã0aÍ¥g§80Û%‹#ˆ‰8%Q¬á†tÈkÈÒŒ™Ò»}@}°aï°‚¾™L%ˆ•>¸#9êÔIFªZÛsU%muDB$ø`‘#/D¨#9P À”b@Ù„m‡#/2؉Ë% „Û#7ô««¤•#7ˆˆ]ØT’ØLÄù±á+J§¦P2@;Rú.<îÎz1 T¶ØÃÎë`ï`Ÿlptùìý¾² &<ó'c„ÌÒ’K´IDH<öÛ®ÏÅñ?yßB›¢;*wîüP?„Xe#/‹$¤€pôü4çÏìÛ4û{(ë¾¾ìÓ3ÇŒïD›J0Åêp€|ÉÒNgŒ+©™áÞ}øûJá¸k4´š]F8AhIO!$0f¸Mñr£5éÀÉ1(Œµ¬%È#N\ÌÆV,À˜‰#n&šCËKh”‘”dŠ¬Èƒe- np@JEŽ‘J I`é\L%Û £J9¤Ê”ØLCQ´R™XëY!B4†H.Ä(jb#aK)‚¥#@%#/v¹Ì7ÄØ Ç83'¦ï.*/j˜‚ph\Bjmvþ$<ûá;ŠøöNò`ˆ"ä§Ýìý¿|4ç#9®#7j´t#7μC+›q•ÎfÊ2}ù˨×nÂFoG¼=þÅQâ.âîX$d¤’„p(F@Äׯ#7—¦¤.ù|š,ø*,ßC¶¢è#/LÀ†‰·•0žp5!žÒ=†ìUZÓaˆàÅ¡*–dÊIòû´Qó$dž»ƒ€¸ó‘'¿œ]ž#9Ä't‰KG:¢+óBpÜNV±±W]o#95¥Á`P/#9ÆÛ•ˆ³¸ãêí9ac©¡J`‰~ó$úûUЊ|QáíÙv¯y˜’2#–m%¤Ò¥™RÅ1¢Í4[ck0µ„Ùb(©¶QªüUäòmååÊWP!ªtf‰#7S‘’2Ê`÷=ç{›í‡Á™²«»Cm‘“ªá,d v¿§¹Þk ;@Q´ÎœGÃÇÄ€tŒ4á݉°dД´‹×‹ŸaÉø<9{|<‚õl¦]|èõ‰ô?NÀ)Ä•Tó"b—¡ì3 ’A‹9¸/>4dMp[ ¢jKÔ1|¾pX™ü®M8eà"¥¥ê,H…`LV8øSf)Ã×OÓ`µ)m¢jŠ‡1‡gq6Ìt;Ú8[†æ–a»q1ÆàI²’Ë™»2‘6PjàaW#7&;3h$h°aÁÒ_ 7Æ BiDÈú|U{ÌíDZ²Hl´šU&”•3Ú5#‹h"(Ì1yOD®T¸JBiúœ"u´C›u”&6Ç€†Ð‚´’ŒXÊð‘,’ˆ¸iCµ<Ž)‘²àèý½ÏŽTî}ª‡Â mÆþlZ4­M‹â2™YAÍبփŠµ¡‚صZÃi}†e~¶]#9Â]%OZZl}æ0 ¸äE!YG§àùÁÒiòY¯bÞÏ$! õýª©²€¯ð#9-$;Â\ ˆX'³¸ÁßyA$#9öõ„íÙ˜´ÈÛƒAêFÇ"=§µ†²j¨)õú7è{Á¿]#9ˆ2J ŽC)•‚K#7wÜçmçâ¿D™™vlC/b¶†ciâë£u59äpC²dú7äóƒnDì1(E˜8@õ#7wg_†áÓrÄðD,û}‰ÐsE˸WXÇ¡»¯þò—úÉTÑ?5ˆÚ\#/­S˜Ì#/Gá‚ïôâiÓžÃüØ9äö3Å}ˆ|`Óøäè‡~Õ‘êB¦ q’‚½ ¾9ù'ge‡Ñêè¢$"hìh)!“‘âê6#L»«¦FÈÙŸ7y‡ÙîÚôñ¶‘QúøïܯùSGÉõzÄÇ¿)±Â#9‚ $ªM‘QKc+µ*Ô”ûå~Y#7#7IB”¬I0U-BQ8/w‘ßéóèñtpQµ%ÒÑL_*»²'ä#7žØVb, À“ƒ|xc…ÈëØaÐ4‚˜§yÑå~+ðž=ËÙ׸#7ô”­#/Û½`Í+#-! )šÐZ”* Vl±M…2B0?0áíïöWo#7y×ßÃÎ#9ûÏ#»çŸOv¬ªBÀvtÙLýPá"cåyPþœ1ñ¶¼šfàn$Ú’ìÆ©!†žlqŽÙ^žì]¥ùÌ΅㶡ÔRRÛø<<ÉM³,Cb¥”XYÅã%Áž.Æ Ÿø2`8#9(€iÆM†ƒX«¤8²L„”°ìï•dA¬„ÌÆ36“N…0 J…ÞC%€¡Ó˜38Ë*»svÔUÎÔ["Í[Ë»š%nî®î¶“eIR¢ˆ"’€¤Ö`:I5Ž°ÌWG%*ÂC‘m¨ÅFƨÐN»½›ÛˈµJkÕu·SR˜qÀ74ØkX«¨JF#9d™Mfd8™Ž0Ó™ˆ1„b"fðêÍC8L$) 6€éÌZ£}Øl.gòŽ{ä­h]…¡bÀØ>ÂøѶEF*‚n-lB#9dúw19aüœ8;Ƭ3T#9³ñI–1P¹{äÁ5×\“·J@d&ÇT*@Ý$9×eZ׉¹à‡†Ø50ëEìþw‡ö¶T6|VÌGq>¯›š|û§©Œ[¡`W=¾À¤ÞOQ¶³‹QÆpuF±±âÞ[‰q!níxç“ãúº©Ý’ª•8º_ ÑbÞ#7œ-ïxcMü¾Ó3\…; >ݼ¢ ‘EW(¤gð¸7ש1¼\×î­„$šb«#9¦à&E$ÑÇÇ3U‘wâX›)%þb: @àíâ¿ jú>²V]×J“Ó[ØÇëE±'#/œ@¹ƒa¹#7°ã"M>ÿXq3ÒM^šÌÒD&§R™;ŽÛºé™ziÌ8Æ~ûŽÒ¡¾;Î 0‘®™»?GO6ud;„K/–r4¼Þk¡Hžèý¢Q8³yÁMÑÀº#7h-ZN¤–ÁQHXÜG`Ìk#7¶‰ÄùÓÔ'Q@äóbBWgFÜÃœ#9 ø¦§t–i¡éî~¨r9Å<*UÚTi6ÅE5Ñe)·S]5”U¢P4 EÓûUôþ¯/Í}g¬8¿Á×¥ÿ%¯'ÑÝÈ#È]Ý:°K—8Úÿ«êæK©¡óŸT;‰%OU,(775älÛ;ú5CÅlÒÍ?² èÖº „ äúW#7óWÏ“«êÒÓÂj‘£'òIrÔDVí¨²v+çV¶ómAn ”2 0Ý9$½(ˆâúüŠÛ­à¸Fá@ëáNŽ2ý0,¤Z Ö j1#9ÚRñ8˜ú‹æÙ¼×€èˆFˆŒS¹Ð5Oh‚÷ÞšA±dIµ£E°#7dÐï Šžš\÷Ã&ÏqŸo!òdØÆp’`>;ÖI¸B3í8{‰q]Ïâ}BQÚc>Ø=lYì,Üy#/t;Ï"¸ {‡؆¸…6~1(bäùNâún(Ût:U92<ËŽåEU92<ÈäË’¡p¿%$CÈ"’s¨áØEèìÒßNÏr_r·%ñÊQ¬¢ ÄÂR£|‚.ñ¦cò»ødÁ²1òÁ¦` ܳøåÙ@ÚZù?gÿþ_Íûéÿñîþ¯ýóÿsÿ?ýþÿéláßÿwgÿûtÓþZ»µý^¿Ÿÿv“àîŸÿ¿ñr×ÿ/ÿ_ý^ñÄÙÿÿŸÿ¿þßøçÿ¯þü¿éÿÿíØG£þî¿ù÷ùýãú¯Ýÿéúÿéÿ¿âþóÿ¿ïý^j}ê€ÁSûŠÀ ‡‰ûÿïŸÚà À¾€Ç¬‡âæÁþo#9@{ˆr´•wzð:[›|¯õ*dþEëÄß 6Ÿó©g hèª"¤âlR;Nó×èoãSõÝÎî¢ILÌùµ¾…B¼S0?†à*j±ŠG¤¸î£ ž]šm×g$*dSÓB»Ñþ½^>Yd™#/e’ó'þ9CBmÈ ÁºQÞH÷Ï#/íׂ/§åƒé—ý"Ü!dñ'¯a¡ß‡’%@l‘ˆsÑÖ#7ÍyZcYå™E€:Œ:7sR%ÿĽÏüéì$®Sgþ3×y;ò¼숄ñäþ¸ÿF/#9]]³˜RñhT°ÎzáŒ^e[Wÿ\7\´ ¢Át°!æ„ÊHA–5ô‘¼újå¹O‡xˆç/ÿJÝF¥‰‚´Ç2‘µYÜ­™Ÿêñv–½©SRª ñJg––™E¥ÖB©¦˜)þü,‡ŠTÃ!ÁþýÅ¢MUO FîÔ«íM"eâÛBîó´äZ!¡W*•§góôx¿ta¸#9c[Ò»›0’h¥Ñ¿û”#7þoNîË+¾ãG­ab³4DV#9°=˜©…&:òïé‚CR{9p5 MMbáÊvÛWŠù9ûŒUÙ`•¥ã=bc·«N•#7êU!™’8qö‰Ô‹ÉAyr–á*±°ãKâ0úÿ ¸‰™Ãÿ„inÙüßY#9ôƒìÌa#/çZ<Ü÷>|^&z¶||(FT`†¦MÁ?)ëëÿ³dÉ”èz:»{³°Od$ÂääSѶԤLm ÆâDж#9¢­4¦V±¬•ŒÍ$H° 35ônÚºÚ6!õH)ðäø”å#ÿÿb#/Ç¥StU§0X" ¥±I”Œ 8[¹b¬ŠqèüS»æó¿ÿŽÞ9Bþ;=—™ÞFréIP9Æf?ÜçD2¿ˆ5Ç»K®¢ì´*©"(”ŸP–Þ>)5ýfz’ã£4ÍàëšyŒ‡Vz2C$nœ0¶3oÿEühmŸá¢Ûð€^°ŒèÇ"îÁö´íMö(;ã@[å%®ð†=#qd°âÆõ4¶^ùPû;ëo4%§4ð֌嫽FX$¸Ã¦4êñº!¶j8,'ÍE† ‡Õk…_ªÜåp|±ˆ„­Ä•è,µÓŸq—ÂZMîÆíËô@ÂLPñ…ë8ÃI©"¨_2iiJç d M:…v‚Þv$¤B%¡* ‰!¿jº³v mÖå”°qpä‡71Fg©d9èÄSÙÈtI÷ï‰×`á ðñæ ãR›e¶AÎFgdÞÍÉ»(ó(³à6#9i#/!‘RÅxôè.1è&‹%Ǖ׋•IGP ÷ŸùOx|6ö¼׿¥K@SvLÿñ½ÞÿÅ°õòO:=¨ó}˜_|l'õ°Þ¡ò)ös?ôÂŒ2‹ÕêÃ×Í\#9ÀL–@… ™0… aÈb%’‚!ÝÜE>B()J‚x ËÙô|ß×øt>LCþ{ó ÅD$ìðø!ð}~Æ·£¦¦eñ²Óú=g8n!¼¿²:_³zîåéñÃˇ¸‚úaûíÒ~¾?¿ÛÑýŸóŠmwvþþpŠ¡R‘î3¦…:Ÿ4#9RÐQKÿG¬#9yßÿ¿‹¯MCÿà“þ£Oþþ=EC÷²ØLû;?ûÎÞþ§ë šáã—QÃh³Æÿ€¨ þß,|þ>¯ö»o©~ŸD>Bì»CÊ#7}Ó®Îéèè!ûWküïû+GàŠ%Mbå#9ë;ãíáò†Uïó³ðéGDêRAþ𔔶‹YÀé]¼N*ˆ¦pM÷j¸\eœÁ©‡|Ž!ñ÷í:vÑ: ¬¬W9boÜ1yl%øxF‰ÅDµåm9„ƒíöðÚlñ9ØpŠð¥‡KA„Û$@3\„¡ œbÁZGC.—††Š$\ 2µ#/¢scƒ #÷þÐWpÒþ®nÕ¯ÛÿË’ÑäS×ȪÌb‡¤ð0<þÕJ ŸË° >ëum^6\ª®ÀÕ/Ô-²Ôö¥ÁÄp_Æy?_îÿÈ/÷!iXûh.@@ ÿx_ÿÚ† þÅ?À6ùÑ„fqQÿ‹¹"œ(H¤„¼#/ #<== -#-----BEGIN PGP SIGNATURE-----\n\niQIzBAABCgAdFiEEivIt5aBoIuNHTzxwSbTGfAUneqoFAlyFMaIACgkQSbTGfAUn\neqoHkA/9H11S84e1r7tI8QGS15XwN1bV3KR3guTtnIAt+TaILfTne69BNMZi5iA1\nkRzKt+QcCfjI3HsV5pLJ1X4y4FZEPx4kRtVkFBZYEskl0MNwRLQsKyVEB9T9/dhb\nGP36OFXirG0iGg0qu8IaUsSLfAk/dW++dYqfB1T704FC3LyN05ijMsu5m0hTrTQE\ncUbNbj5cm9gifkbECuaIJQEhvM5TCMR1r8yoWINtD9gLKwrbNAv9f4qdFpqooLRL\noLSPWUSzcq4jkGM4jHosNh3kza5CNoGPsL470tL4u54BgIJuDO8aWAO7pDKWJgn6\nswuVol2v7QvlEb4ejErhP65yYwHc+GbDcY4FDTzL24yt4p9QZils7kAtojIsOIv/\njnE4BpJA44ymB0SKIJbK8VJfT4O71U2EayXGvSpdbGRQt0wD96wDsexLXNPoT+m7\nLiQABIJrYYMZPd6TR6czolS1PjsIb7UTIw3sF16G17xuPM0zDxlULCB2D/eMCU+G\n3xoYj0EtNY/A+xpWQO9lOQ7LqJVTjSChDFDajguslY2vxD735xbGDbGCLtAPQRjm\nVFC88WTnGy/cZ3fFlfLdaCRhpu24y9WVlTYgchSBV83gkD9gnJTvJ4q17PKUvxis\nBMysLiz9gVqT8Ic6xbCThRQ5K+pqvn3isYxz/iEm2zGL1/V7PuU=\n=wpUd\n-----END PGP SIGNATURE-----\n From 5c771b851aaaf5e42d5d5556c3d4d3dcdc8ffee5 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 7 Jun 2019 02:22:20 +0300 Subject: [PATCH 202/211] waf: update --- waf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/waf b/waf index 652bae2b..b35987aa 100755 --- a/waf +++ b/waf @@ -33,12 +33,12 @@ POSSIBILITY OF SUCH DAMAGE. import os, sys, inspect VERSION="2.0.17" -REVISION="0b58f6af6b52bcb6cae0b82df8107844" +REVISION="da8474e646911ac5657990d535080c54" GIT="31da55afb92d9865019eb5193e874d1ffb86c522" INSTALL='' C1='#9' -C2='#7' -C3='#/' +C2='#3' +C3='#*' cwd = os.getcwd() join = os.path.join @@ -160,10 +160,10 @@ wafdir = find_lib() sys.path.insert(0, wafdir) if __name__ == '__main__': - sys.path.insert(0, 'scripts/waifulib') + sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'scripts', 'waifulib')) from waflib import Scripting Scripting.waf_entry_point(cwd, VERSION, wafdir) #==> -#BZh91AY&SY5I x¶9ÿÿÿöÐÿÿÿÿÿÿÿÿÿÿÿu€ †¬ 8ÁX0E‚¨bQ<{Ê÷Ü€#/ #/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/#/´{é׫m½°MvÇOcÝ—±Õµ«"P}ïv’w·tßvìØtÝ·Óîz8™gY³£ë'ÞÞû_s©³1—lì®ÙWJ=õð;Ó7}ݛݘ/[{”ÐuïuÎl zÜš+££Š†´HÞžÊknÀç}w¶Õo¬úõy{æï¼ãv5ï4uÓÏ-£Oi»­ç{Ý=©>=÷[Û¥öݧ€d^ö­×w7ßg¯#/#/#/€ôØ#/4§Tpy=Eï#/.`èu#¢Í’·£ÞÞÖ5°i #/ƒ6Ûnév4É)Û#9êŠÖŒ»a¶‹Mt4kE]†#/ ¢¨”¨ (¬TJOM@#/J€Ù•U@E²ÍC½õ•çºÑö÷ ä§{Yë¯lõêïníXU›HÖUîäÖ%)Öûï\³QIOwAöòÞ7·uißZv3ßw¯Ù÷7¶É•E[gwºúÇ{¯½Ôóè’Ek³æûw“æÎùœÞõèw»×^ÞÆãݶº#9]"#/¥RAÍhnî•]µºîÓ«§;¬v{¼ôÎóºW{é]µï91»™Ö"¨·n´ësEPP#9J¤@ªVC׳•¬ñ{ÛÐNÝ^ºîÖzä¸ôæö›[»è|ž|¾ö÷^}‡«·Ð›ÚZ6Àë¢ã½Ú8y-ñÝU'¦½õ¸#ÞÏy“wxç½vg¦æšØS½³§Ï{Öï}æù÷-Ýî=sÁ®:y{­ÀÙ™š#/*o®ZËlÉ=}îó@[šyÙ|¾úy[-«»©Öîînv×Ö›{s¶I&Õ¦ÞÖ»·[bÜO½»zÉooíô¹`¥ÖeÒ¹0«¾¾Üú.ñ½á×OˆîomÞÝžöU{eÝÜÛ»[×¼t÷M÷Ô8ÙlJTŸ>>ö'}»­;-ÜòzvLÍè[ÝÔÞ÷q¾ÎrÛ몘㛅·#9¸9ež‡0#/^Jõ{Îó¼Y»î¥·»¨u¼¡@#9)I¢Bº÷iÝvÃœ‚©»†]š,_x£ÜôÝ/MÙÐꫯ^C¯,¢óMÑ·6´çN¯¼ÊÇvo:ëY;“½Î×[»²ð#/ÜçT*#/!sèûízû·w;Ë]ò:ìÚ}·]Í.ætd¶rä}]dã¾ÞåOWcJ“ëÍéË_ѵ×ݯM#7©œCu6ÜAï,u\‡¼¾çÕ}ëÈîí]73À¤#9hv5må<ÝÛ·®Ù&÷;×7uvdžÃqW¶´iʶ÷Ø=Þõ{ÝÃ5jÜÓ¦Û»»¶Ò»—o{‡šÛ×hîqôv½Í[õå÷Ï®ßnŠîîc–m¹š+èÛÒ­œK¶ì…xžì8ôÈ«Æù³¨:7a¦[­u}µ9o»¦:ÑuµµšhSÞy.Y¶¬úèú·›onûÆñ‚¥Ùׯ_Gvöu|ãÝÝg¼nÑ2Ë_líÑïeÓ™ëÜîÓ§J=z#/8T#9Tz‡vÞ{0»mª÷:ç¡è9y LÑ€{ݻǜú2Ó}oT#7<€è#9Om[yÝï(#/RæÛ5¹ª÷ßg¬@iB¨(U­JîT)zõ€]S½Æñæ&εÁëÔ3}ǽ·®ºÔæÚi›·tfŠE ·VÅÙÒ‹§1U…WÜï·ßxëi´ß,íl-¬¼· éÏhš²nùί‹'yóØÞ•g^xø'Z‰'Ó¶¹èêö9vÌí+Ý™»¹·½åÊ¢ßw]÷‘÷}÷·:ÚÛ5wvs»<^¾ß÷Ž¶À¢ñ.&¸4Ñ#/@#/Ð#/š#/ša2 ˆjõ‰uÃæƒQê‡"©•ñr[ܹÈnµ}ÿw§25gßס™Ç0‰ñµf[b#6Ý­æÕ’EPÄ/³X {zႹ#9m»®QéÊ7Ìí|_;ºîír¾g“x®WÁ\Ѩ8šë•ÞwTnQÒ¹s%òÔá¾öÕçàD²kš#94±ˆ‹m1™í²àÀ0{Ïf0Ÿ#â^ Dæ…#9ŠÜ¢¤E±È…´3Ó–4uɨjÅ‚¾ú)Gèa¿Úᛜû‹>çíÒFßf dÿ~££GŽðµR#9€Ž(Ÿö{p6¾‚v²´ÁýˆVÚMód4ëÉ0k柟xjOOÃ(Ýñ|çÌhÁØ&Û]FrÃ0ü¢žj¹ƒÆÏGQ{ïø-rH ÒSSòjEE#91pq,Ì\}Ûñx®Ãíʼn²Õqe¦Ž ÊNn¬îM8‰²Ké^ë® Ê•Ž˜ßÕµçb‚¼(Cëe ½9ÕÅ)ñÇÕ~·= à`ø§nínœš}l”‘KR†Jv,E¢p|sq¿ ‡ƒƒÐ?{&EÙä²٪‰í3 ûl§,Q£S%"V}±Æ/‹öb§b¹d]T²ª ¨}ÙÅÁ¤û¬¡‘´=È°÷2¢¿M>¬¬,‰±Èj[ÿ9«íÛÆ-éÓóašLY|Ýuõz¡@c¡ò ±#7ó[bV¯¢#cJDѧF^(q¡Uˆ9j˜ð©W[:]¬­|kü{*gZP¨:Щ()ra;NCêPÉSô}¹¢=y”—“@Œ†ˆRÅcå¿ËÙ¥`ÕÊîÄ0*j‡¿Ÿóh¥&Hšh©ME'Çß¼oÞ:µºnœ·0wÝÄDÑ:]e* „¥Q)—5mç}ëÕä@ÊU’¡ð¸ÉhJ¸Ã…‰^Ì2šR §Òä›åëßãëx§¿wG\ÆÆ¢¤Ï[ÆuBQCò°ªŠJ`&±=w¨‡·Ù¦ö`=ÉSe…²SLPê¨iÌ Â#™­lÕŸ‚I„‘½¶³Æ#9ˆ% »ìC”a+²íç£[X0ÃBäFNO$¶ÃmE‘„ÖBuµ y³!L®÷`dó£ÁÆÉE2„R]U¥"½;êÖFþUjxhRÍõðÐÂœz÷Y`Å„àÓD%Œ0£œœˆ5¬”ª¹=µˆ%]…•%Œ7g´›$Õ—o—õð‡è(*‚Ì£ø7fî<$›éG÷ýzŸÇm7ãÆ#9A`£×Œ8‰Ê¨ó¢§Ü’¼<,-UBÄN”Rv²”Dp¥ÑßENQÊ©êüRý´üªy]#9'Ý},ã¶Õ 3Vpzc{éPùT©†.²ãÊü?ÎçκCiT4á(kÂC›¬0âMú~³ŒY­4y4kM-v¥I»QT”™…‘¯:»?/òw’0_*ÈÜEØ ÆK¯oþµm¶žY‹ìöLöD§“ 7§“F?¦Iã:°Ãl’Iév…å¡ój=É›:ºb“…~ª¡ÄËÒϯn=l®)]=3^JCø²MX /szø‚i·ŸRK“oô1m¼‘†Hm¢Yñ°ûòÝaÎwÔ‡ék{ß?íêµËCÏ’ñ’"uN 5C(ëùÙ³¨óªu)Ҹߕ†\(œš?FP§‚>wÏ]pu03‚bå'#9ëõØZõ|æ¡}Ùâ¹/šuBÔΤï™ÄŸ_{¤~þp^´žhý{a¡*‘Ÿ’@:@ú¤â÷Ÿ6uLjÊÙ !aâþguIêÍU&´¶Gch±y2ŒcâãXÙg8qÖu&!/²q(q<åÁ{ÞÕçøs›«ÞÑrôdn®$g ¦[sÃZ=6÷—\Ÿj¤hDÆY»aà7çÖãz…U„aî¬YLéßV»*Ò„˜p"GÙ÷]ö¦FL•Å¹ØªThÎ0y½B’QH£+˜\ÍʳޡÏ\ÉÒqxÝŸB¡ÇL!À‡w0Œx¹Í™àémP|×l¤0iPûÛAn¨ÂÊârDþ2oêÍb5 µCnãSqãʽµÂ%NS¿/åü÷¼QiØÍ»ÏLP_>åL’&¹†ìl~Øtná%ÛˆáŽzR <’I‘Ð$ÕäìG£ö±ÌWÝ¢d"§£A’-k²c ôå­Þ°ÓYù¡S£Aý×Éê#Ü4XÜŽ#7ƒ@ßYF5ÏÙU7‘³?¼ÝZq>héa¶RšŠÞÕ^žFÌ›Éý´×úTÔr~…PéT$4k˜ñ(˜FóeõªšgM;óº°90(ûh¤TWôL ß³7J*/Ë`"Æ)F“[ëqØE¹O›sF3ìèéæïÑÆo›h‘¹¢(2œ÷ï‹ßO£Ý‹¡#GŒS#z´:E·ìˆ¿=×gú°)TùøU?mñ5„Î'}ã—‰]½<$ù-¯´6êd2iF£u´»ZrvfdmýÍFs»‹ÁáÓã¸AËÚë“,be¨ÎZNÜþ&;:m°»W =/º©No¥TåÇ0·‡˜~líºÇ°½è´"(>¸t\:çx1TS–0I×ðqÕžúªCÉ›æP‘AGTíÒ±©’û¬¦rTl\O·GÒv³$3Â%FÛk>š¨<‘ç¾Ðk£Õ‘Çy¨¬ÛA ë§g‹ˆ}ôéf¡†F7v2]{l9NT1]¸†"‹EuôÇ.U—J8Ùÿf´xð¨#9h6ÀêD´ðaK–R‚±7gFTd.W=uëá¸öðÙ#9ã[#9aȤuÙÉwÄgÏ› K2êxßìšé´ÿ¦_òâmüãaçÌ­ Þ§x§8vA„1ÂvOì7þˆ.þ»±ºxWä­û¡Ú§~/7/Ä9,J&‘ä*$‘CE#9¡ÃÅFAöÞ®Þå`¿F¯ÕR“5ï½Ñ<¡ÑéwŽúøºgÐ$E# K‡&±ugcÐOù¸^Ÿüîõ\ïÇ9¡uv ÎP´ò˜Ðé3“^[ûíÅÙݦ𑬆QŸ"åkElæ#Š¤:¤*!šãèYò=Z°PŠ*ÂåT#7™Õ)öžkzW‘¤1Š×_7nšj½ Ž[CF}˜øÆÃ݃…öYåêp4„R¡oj·¾n\†çfåþ =I†*PUH1=d·#+–Ç…€(±P0Ò¾ê^Ã#9«Š©–÷wW3zŒJI\uúš7Ò/·^ßG™×Ô4±ö4¶Îjø%qÒë•~.tM^.k2(Õö@×—ï\ñãT#~éË+×gƒÿ•8š+Ž®›e;ŽÒˆG¦ï¸š¶éZïCÛ¢V%ÆÀŽÛöðæV{áeX¾hG:øÄ¢RïqÏš ï :ò~•U1žÓ!f  7K–*^üJ¿— úåøÍ(æ‘W¨ê70þ‘ê¿ž\Çgôæc\zÆS|¸Î©¬W¯NéÊ£W8*piø(1DEÛôĤÿíÓÏázpΰûž?NGó÷f#9•ðtáþ›#9’,0ºÕÝØuhé©í±o‰c‡ÈHotû³·æEÅ|õÃÛîQr‹³Z”,ª£–.O˜ê§ìç¶1Ë™÷ù|¾›Ø½±A#9s]·^c40#K·òDƒçñžQ›q§"% ‡ í4Ø{Tn°HÚ‡I4Jr ;‰'vzwÑ_J¨©²í¯“/Ï·1Áª`r$ÎÿÓ– (fïïNQœÇ:uºõÑCÕûY6Å:ЫNØ£=(–ÆO9¶Wwm®žK¯LƒCmëV—Ùøç–—žði—¥!¹~Ý|oºÆÐüfßžGY:ºúõ‹‡ù»„*IŠÓ{c¼ˆç\çŒF‹‡5ÄFÏ%e5 öMüÕ"“Šu“ËvƒÑ÷'Uy‚ã{’Ù§Làò²€“\ÌÎÁüá´É2!Nî5âäƒÜÒlëÃJ×``¯\ܽ¿ïÁæiG‹5‚£"Ïñé›{ª¢rÆ6uTo%‰ŽŽ}(4¨ßXx&‘O—€,C²aB’, y2Y”ˆÓ Gqš-ñ:9Ö!­ZÉF©âèÌF"?Ÿw¿w&]½™·zsÇc£ýJV®OeöÎl‡E[”ðk°ç\b]#9Úcý$¯ïE—¯Iø£öKkç¶:Ð~¸ËSøaðݘǒ7ú"ðnþw¬^‘AQñ Í¢†nÚÄüéJ~ýi6¬#9ºlã}zQi Ólª«Þ­Æ+”iUˆ¢,õ+äà&´È¯Ôá?ŠXOÐÀ£Ca§É \Y@sãg»_Â×ú{ì öQÜòåžihŸis’ÒÆèò‡hµ¼)ÐFz$‹ ³“pÕ?l?P3ϬAÑ47\Κ–¹é4íÊ£‹5™AðjÒ:¢š¥³–Ôqz~•¶°ýO#/C‚n™¶Œ{k(ËP"1b±ûlņE,VѺ›m-ðCèÔ_+#Y.°Ñm3,+ók¨ýnsg“:ÔÀÁfõU«E+m"q'„3#7–6\j¾uª$ ]â6O´OE_'ÂÝû¹î‡dƒ:P¸˜‡®¥ß¯nœkð³Õ—_$ºP‘áùÙ5˜ˆÚõH¹Ö‡*ŽÅŠ»Å2š¿tœaÎî$ÆV–^nžQ ‹ •.â®I;Aý!(þ|éõcZQ48Ìnüîã#ÏÔªXª*&¿•0^€ðj#7Dæ¤GWg‹Y¬¬b¶#ãg #711­ñp£0p¦‰ÖßNÙ[`˜ÕJÊš¼vîÜÞ'k‘KŽ«®1®å¤ªh‘ÕdŬ­~ŸÎç#7€¨^9‡òò`î(wØÌëGxû’|#9’IrLŽYC·øIS« dŸ€Úæ¾0˱ŸT\lA“aþÅO]Ýžñ'­'Èð#/A¤£ÀˆxÛ÷:éüãš#7ê.ï×V¿ýý;‘pÙ…ºÇÞö ‚Äpžý‡`x¾ž¡´rd®h*QÅ‘˜7’ áFWÙé?íú¸ü‹ànþû69F¥<Ê7mËÅ"ßY1Ñ÷w rV"ØÜNÔLÈM¤x…ekm$}Œ[i-µðaæú¾»›d8Õ/»ouDxúFT¦6M›|²hA³ì¡œw&¦E8uŒÁ®[Â4íŒ95jþÚïbÔq‘½R#7µ¯Ý§:î-¾ŒMŠNwtüuÍ<$;"°£QÐj2H€jUñó2PŠWÈÈ°Q,-(Ä3•2!ˆqK,YÅ[Š¸ÿ™÷`,·æTúL=+6ù#éÅ8ßÙ-4]/jiUĺ™@1çøö>v.5bÕ£CÞÛŒ¢#Wqò*3}o×7À>çd|ú#gŽ ZP¿m»\ˆ&ô’ãY»ø@B0/ä›H©ÛÛÉœ·Gÿ#/„êâQ‹^¿]«CÞ )H¹[걑†“3>w¨U,ÄMTaq†«#ÝøLíc€’Arî-CŸoÅÎÒíÎbþŽÛMÇuÒŸ'Ê[HÕÄz>%üÞYÏ ãt(2G ![ë„q¯}=5ùî”iü­•Úr ‡'^nŠg®:µË0=½¼½©~þ…\8¢ºWìåÐÓ“Qʦ]ßÕ½úÉ#Ñf\q#7ÚÜ Lé†ÙwM#9/Zbµ7îÈ×+ãÚõ#dºá‡nþtÛ) ©Áݳú:3/UW«#76ÿ¼T•"³4{múfï=ÕÁÕ2ÅÓ¾¡pS²¸¦q@Àò£™Ô4¨îàúåß·‡ñ³$âµà(ÌëïUFÍ7Px[‹lÐû&þ€‘~¡Ç@¹¥!ía4ýšQ™?»ô[ƒ~â”ÃnaÃùÆqñךð"pg#935JöÁ.ríFÚx¥ÆÏD@JÁƒ¦2ÏBdÉ,¨—#7Ɖ>Ô³h´ØµÑ”£|Ãœ£‰LÄïÄå È •JQ ˆ–?tÜ è!N˜­ÃÛôME³ñî~쵺täÚ?N*ÏZ—eËk`éqù¡+¡h"[N]EU8‰šÔ(±—Ï !ên­ö`ø ¤ >ƒÎy¢yX?È·>™Šèÿ#/dS”¥„Q eò9j+{x$T– þtüÔÛ˜ÀB‚”«¼ZÞE˜6ŠÕíýÚ×\éí½EÃ_»70SìÒJA#Û€›Á‡—ÃŽ™ömÿ¦9wQ:¨‹»àÙó¢zLmîéÿG—ŽÛ)Í‘*÷Yþb4ÉÖÌomÈ4 ]µF“m'€êÇO¢cÂ#77ŽÊ‰Á`(eô¿’ŽšÆTrÒûJ&ùâs6iYκ/þ ÐŒŸ\töPÈc½1Q¾û˜ 6Ž–Fì(™ #9¯ŒNǧ(ÿ_w^½¼ûé†Þø»?¬ ~þ¹ oêp  $Aè%þ®Ù Oî`ű†—ZìV#/ÑxùnÙTF7IGœ|á¹.…Rœð%³Ì÷ ¥#7!pËR o±;€À{$,õt«BVøN­ôò#/‰ÜJŠØ*#‘#/t"£:7”cŸ èm%ãòp}ÛK]Œé—vªõÀ¾†5©µ^1€±D©çøñ¦1†‹‚öM‰`f'^¼œge÷âºu|‡ì×iþ%eû=‘øý²¨Œ§G°Çý_ ý¬äÀç@@Ê"%H(@)\‡küüð¼#9¶ýh(´£M[T sA²H}>aß)|ŽU$´ª{ª’$=îú_}†È„.ç5ÿÄ$€Y’AÏzùU#/d¾É'b»X°ÏFHÐ4Ð+üƒ[Ù’Gµóò;úvmi#7§d‹œ¿>|GÑñú`/×mšEÿäoÏÓµMŒÜååµ.ÍÚÖà%Æ_ºù#ë:iÛüôýáÒ웶×uG'OÉɾÝ×T;æ}÷ðåQõúJ¢Vúúž™âž?ÑìwSÒ(H„ņH,×vbb"3Ì9 ,ﻪsîà¡ÈTTG€¸¨Ñ|V#/r$yñÒtJÔr‘#7¸ý§ðã“êx¦Qé-åþ(!qž™•¢]í¤„3x®f”"<:]>NYé«c}Pxß ÃAH@¹ì5Ù¬j~rp¦F°ôo:.Xÿús-#9!Îå#9#9«|úsO^û-ù{û?'I™#/t÷X\]êrÊ°ìÝ ¤ÝaÏ\Ö†öøæ(öw¿MÍ ?1Í„#/Ë$”³Z¿Ä|5aa vx• mE´Sa±ëLcòžqç†0ÌFÙÐÿ?La!cüúu¹(HFÖ¡ìñZXƒÉJîùÄ\ú['ù–°<ÉÑžò%)³8ëÛc ´•¹öpá"–§Ó{ѤذŒ4øtü0nµé–Ö·ƒ”N( nœäë!Œ,4Çë§ÏBbÞFL¸=Møñ7¦t#7Q4q%AeÖÎ5UUH !I-ßÒÙ„œjìo£Á}±èyœ^Žæ"õ#7#lFññ°Óx¶ŸÂÁ2™ˆ£1HSXèMÔ?¢´¿m#/©IlåwÇܘjïk×;Øxâ9^ ßï±Þ`ß“'ÕrÍ#‚˜Nvü–@Skš<³©Vò ®øìéý&Î|‚Ø}ˆ Þ˜r„âN[5Ìú"™ \¼ÀèŽÒØþîÕ'¤é¦<ÚHÃÛɯ¤1SöXЉéZ.¡Þ=#7úf›Ù0mê²!5-S8-ñ#4“\L1=#óývQáûº¤a¹ß¼¸ü¹¥¥lî;>å‡wg#—BÁ0Ž1f$Fª¼Ã{òŸš›ÒéÌò,#7¤:vŒJgiãòjBI/¦L}2ìÊ8·mêÌt‹¯—#9¾¾ØÐ93z7ÊÓ¦ªéH)´‚ðDˆ,yk¬íK}5V'ýë?j0Æ7#9#/¡›q#/Î0ĵ{=çÆlŸãŽ0=3›÷˜$àvøyrYøÁ¦%CL9ÕžØc%.ƒ¿ tTã ‘Ø+.¾…ä~Èì#/l ‘§Ñ0 äi‡…àÂåÐ ÈH¡býZÑx½,@SH.Û'Ö±©tXk²Hî5â ÂêÛ’î~ŽÅc¯ó}¸V×ÔØ!¾®`XžðPŠLP°"­Ó=žý+ÔÔëžgšá•¹[Œô:Ó!;/EŠ¸¡|›C7¡¸-$Æ4ØzÐ^ËÎþÿ¹LëÄ<„wi¸hrNR°fRµç$rÆÆÔ²#7 Öb1(™Z(ÂؼvqcLK#ÆÄR§¥LoqGd`Æ1#7(0¹\Ì+!a—EÚÿ!»ãÍõg6o)£‚iOïÌ 2š÷mCÚóÒn,xF1#9‚,"¨°wøÓÓÇNÓ¼£žx#ExëÊõÔç·³ùª‡ %öoÀQ`À8ïÔæ GëÞäç÷¯˜òz«<áÞ£#7s#7Ù ¼7Æúe>>­´O²y Ñ#/åY½Á®u! …‚0&$%#/‚0ˆ‡Û_&d?‰|5÷ñ§ëÇÙjpsï(½Ÿ\<¦ïµÏh:QJO"œ´ÍŒÞÒ!Åtã~‹fÁbƒó[U¤’äJ[¥hŠÁ®Qx-@µµBe.Ë<Ýu¥ÂÄ£(0…ׇA &tjÊGWñìï^wãã̦ñ}£t×c$'e»6XDPRrÕ6`ö‘\ðÄ\cå â,Mal$"2or>h ~KJâìjT öbM v©CÁ¼ã¿OÎûDñïæU÷o\b‹˜ÇˆUœ{ªç»): ô*²Ï\‚6éÅ,áTŠ#’ÒšêœIxuY×Aûpv3ÞÁðî­ÇXïß±sew'ðöãšr<Îã’[âݼÃa&lìvÅ‹›Èk6ãÓäÑèXÎcDÉ¡ÈÌ\åꦶZ CÎØÕGërT¸Ü(¼P`Þì®Mçm{ô–zW•ÏF9hŠR8¥c—<}|±-h÷5;zÁÆÍàæÒmßuóëÛcÉz`;¥·Kº`Êõätnª5<⬲mõaE“á/k¼Qxän•êÂHN]ÈC ªaîÆÄú¤ý?¯ØÒR‹þºÝ-¯{awúsA*|Á–@Éè´GÑ ö¬ȦÆô.Š%Šåêã M#ÎäÖÒ=C÷]FÐÐ!?BŽ¢çr”±Ì€»¢€=Õ#9Í–2[B((¨¥ë»]Þy—k»ºÓÇa˜ÄF”j¥²™) ° k°éèé“ÔÐŒ;ôÓLßÛQ_.WÒj—Œtn>Ë„¤I‡hM5#9IÐÕ1\)Œi‘JÄŒéî÷kÝ¡4›ª‘Zi @#/¸ä²qÛ”w†´Gøý;Éò~ú˽UÓ¦,ic}^U£Dˆ’6x³ú5Ø÷-šá¨m |FY˜ß̘Çj^XÉ“ýÎj‡4·Ãžh¸`á@°Š¡JÖ=öªê»Žk02é5ŠØ—fB€HV¹;^zÃD–Üs"Í™±µRŽÊ„ô>iøôíãIi‰„C&~Ϲ*O€òGŸhcF•o¯µjœîVÑüÇN“’–Ã\¯u“Žû„‡ÒÇßl0²A¬š,'#7]1k`én„0‘œ“Õ›48Ã<¼É~å*±‰l ˜ÌF›{?¯Wª¥°øeZ`anï:ÎÈ&ø­yˆÝ‘3’çE›jGw1Kr¡ºÓØÒC{—@Ç%s0R´Úl`¶êXïSHÁ“8‘ÂÒA–::ky6‡R䄽$š1 hÙ$Ô¼áÙ6±ÙBfÊY`Ù,E#˜Äºëß?v–v™5¶¼¼«ªÓBùöíÔo¤) ¡²IM©/Òצ6¯¶WŸªäQ¦F1bhËFÞÉ$m¥ZI°ÓAd 1ã±êº«´ÙÆÒ& 5N¢€Ú¡0 YH&½1[Ók_^ÍÓ僌ÎÌIþ>~þ-ÕkËÚe‹Kü—¼„¨D 1¤¦IêÞ&ËYæ#7í{—Û7éìsâ±æV>äø: åÄKõêíÇ|”4vû©M rVìûšWÞ@Ê,å€D$äBeŸHíAÍÄo«œ0 x ;xù“ø×öèÅ9·ØW«âÊ"nØå»k[Hæ]Ö¹†s‡ÊÀ„ÚhlËš_væ)táû2œœRLîõò„b#7älsbÔ\ÈŽõxjÆا¹_OjÃ\#/Hx_n«lDzqÖE2\ËJîkÖÁ`×h²;\Çöbë'´øçñí¶–þûiLñèám‡ ££¼å$$½ì{®D{eû!óºˆý§V}éÌNĘ^D“®–É¢| ¶†ëÛ¬p;䊳•Å¾$ÅY"•™tßU‰¼#·QDimøŸ-"øõÃ$„ ëYŽïœ“×2–bÇYð‡ ñ¯/³ö¶- 3.vsû±º‰¸:®û«Û¶’dÇpLy’@Â`ßæÌ¡YB/,ÊÂ$ÿŠ-]GÀþ5ðígPùN9)ÐþåF”;PG4_U²kd*Ã:M‘Ï^xX²áb'˜uŸ­å/mŸfýËnŒÜ±Y»é®ÃÌ™X1Æ­Rd‹TÐКaWGWH߯6|ÿ»s¤}œ+¤ Ç徂qwF#7 ˜85ÿ"ÃUÕRÓZHŒQB³U QC³²­á¬¹§‘6ÐÁªPžçD¹KQ#9rÑîü³_nœ1¶É^ƒÂƒ‹>‡E*òŒ`S‘ÈŸž~M‡ÿ Á¸Ñ à!\3ÊÖ~"®“€7y`¬9<Æ}ÌQµé-BJ¦ù½Átñ^_7of»íA|š`¦éB!@u"êYC•^¼&9iÖDœ›}#ïž‚Sˆù?u½ðÔ&f«ô¾2ò×Iž)pó;í”)KLJÔÃ’‰„¤E ’áR¹#9á Éb4äÐÑf!Á°Æ1’ZYiOe)xS.¬©é50(3 »làíÝä72Æ#VB#/#9…€“à”„PB‹‰‡ŒfR¤'Ë·ë b?!ù¬/j|¼äýñÄîäÐÅí¼8¹ ¹C@på[ð-¿hoÑÁ:øFŒŽ_† ºÏòêåÞŽha¤aÎ¥ÙŒ”8j¢æ‰‰ ƒJß·`ýÃõ¨ö³}j¶«˜õ3áñ+ºŸ!D‘i`Lè<ãøñøøÝø›R¥Ahù=¬,ÛÔÂ$iš„ý–ªnýÊ›æãt\4®q#9|‘Jã0¶…{—Ø'2I$Ÿ†®HÊgÏMܯõxÞÄ#7½ ïiò.¢-Ë*Œ#/–CÉó~Îøówvq‘ ¨ìƒ£ñ|£+aá´‹,˜¤@w-·tó]KÏÕgž—ýøÃåoG&6Ê]~¥)«ì¼O‚;aÈ~¬Xy¾NOßáøêø«^7‹ Ú{a‚qÊ#‰ðÖãäjV!Àh ÅÀªB<—¹&‰#/O.ÑÂ÷û:¢“‚øç[¼•It]$Tø໇Ê<žßpLÄ„€ÄoU ×½Ÿ òXF¥$LcM呪“¤P¡BDqØ?Û Ð:1’¼?åú¾ów‹hüT]V9”*å±fQãã^Å^‰œì»YM^­FÕ#7K\VJˆäŸ·÷öþ~­ HqCßÿF³KùìÛQ¾Ÿ³ìù7Ë‘#/D ?:( €”¿£ËÝuð±ãÚáÌù‡ÊTz1úÉ·‡hˆ›h).¢QXl#ÚS™è“øo]±#9-ˆÏSµ ŠfÔ–Mb6T±(¾õÆbhÓb¯Á^ŽÛµ#e†8Bd¨ížz®ÝŠ[üˆ§×P‡Å… oö‹#7ŒÞßÐé¥ðh£<Ù&@nò&‚‚9}-û@Q&ëðZþæ6¼ ¤­ŠL#9ó‡Íý\²Ød¦ui+†, A#9 ³ó¿#7o!’Ud¦a‚àKä؆}2Ø7æ×=§éïþžÏÐþ#9a#9(+!"îñÿ:”¿§ÇýO¯OβŽˆÂŽY›¢P4Ò?ß„\”¤óÞ!kóe?Œ¼ 0Ûº1‰+š'¯üxÁJU#±”T®ÑB<áD*˜’¨¡=¨Ãûü4‡Û>ÝOÍËÎ=¶5Q×Ó;¦7Lj#9 ›`VŠA@ôñàk_ìÌ—Úk gíßÌrƒHÙU;°W3‰Sÿ%]´Ûºÿ–i}M:—øOì‹ö©Jg>óüÊ%Ð]5¤¶ a¤­I¼ÕÔ½»ÿ¸~o~h’…þ¸ü_V†µZ:|_Éû¬˜?F|×µ Ä?yÖŒ¸ìwé©—¢û-Ä1Ç_86×ñ‡7ÝÇ\¼…‰˜z© ¦é$<곸ÀᢠmßßÚ–¢*¡cT+÷ýµÉâüÑð A}n&Q&Åûú^óh#9*(HÎ$ Õ¯HfZüfd9hem¯„û¢2“óùèvÄÐv”]¼°~ùpa?=ÒsŽW 3hOÞ#/à@í%RD?š2#/+ ã#/Á€ô¸)8ô øQ¾H¿kúˆõd5ý¾o“å?%ÿoíV#öÙó]è¢ig§œõ¿ï]>›ãù‹è!×/×?1ëùÀø„K¾“ÜE¤dSþfú¼„Ïc¾ÌÕáùhñ(ãû¿v¾ku³ [­â>‹€ê(ŽDó$f“{“mÂí>{-¬¬üzïu–ÒçJúwI<2~œT~RÑ¿¶ãj\…xüÿ(¥šÎ˜ù?ÜŒ»NÇ,ïw÷lçû›m#k¿~‘Ýצ+R-åTÊÍN¼#94Öþg#/l9h7ê™RfN0¡ˆg Îô†s×T(rÐߪë.v§9ÜÚèÿ“¯!”;«×W©Ar¦îI7¤ÀàFZ9ÛÄC`„Wµ¼¤"”,ZªPÉ-çvѼ.¸œë2jZÄMZŠs0hªo0âþà‚’‹ßmvöëtà|tÆÇØ“½ðNÿl ŸçF·(V,ýlÍœ/eøh:)óaI5ñǘÀDZ›eE'ºÐQŠ1`¯ÚÏ‚C€FL2 š4I±\ößöœ7Ú¨@Êc`€£˜‰ADdã1r—íÑ¿Î=~/‹ÃèõóX¿7Ðo>³…û¹û#V ƒ³ÓÏí4oW…š6¥žÿ¢vÛo-¿G7@ó¨û¯ö4µ|ÂßVN ã´_é¥Fe/[5¿U˧}îö²/€ŸÂ³ú±ïå?¯—¾wÝ#7ëðý>=Â\7ûçÐttr^%8ìƒz±Í²*%Z½·E~;ûÚ¥ÃÎ}^#9î“Ë';å¾4yØàÄÛ·?^‡!Øíñ_\ÙÓgøˆµ;«ðÝßÃݳ¿Ù£?1´^éÇGùº>W¼.b£˜ nëô;I§LÛG7“LÇ£ðEmËÑòÅÇV¤§êOwóœýòÞBŸ*@k>~Â+Û­Ý]¬ú+:q2áÐ+ôA9rù=ï#9m˜–©¡éèdÈy®[e#7÷r-”óð‹zuåݺå{ÙYè±ócY^áõ@c«’Žêöéý&×péÅ9pçþs¶1†š¶¯›¢\ÏUyvîÕ î|Ƹó«ßâ†)eÂ#7iâ|½)Fû;åm¥û®ZõÇXñJ.‰6ŽoÇGÄØu–k•¶uĵo`6óAF4†¿U¬Ä¼º8°ú#`ᥖëæLo¿X®¾A¹‚ÅÌÙ…¸4d\çU\Óú>=ê5rÙ£>]rw'«›“ÖøøóaåßÃÒwk&éc½Þr%îöp»U×÷N[ùÛ44¨ë î3^çìC#7 ›2úFŸ¤Ú 2´@ÖôcL¼Lœ.]¼q¾=ÐÙ9qi{GH–Uú<”uþm·YEß½DÊYñØ–|[èùºxeþsLEí¬ßö|}Éæþ^ï|©¥Ø]ùkmš¬£º³õDþ஀ênõOÌ»;¾&˜}†ZGºp˜Ù«)/VÀ9~.š~ë´F£ÐwŸM÷>¤Z8‘ØÚŸ“æ¯×êa»\—Ö¶“n‡|ŸéÅøôõ9´Gß«G%~W|Móp8ÎX€O%ðjycO÷|pqÝ÷goÞt2@a¡‘SVCËÚ‰ã7’v]_wÁül··ë´sïÓ‚|ç÷›è?qÿiîÑ·}—îŠf+Øÿñèöz¬²Þ{‰Qõú<þÓü0Š“»Õùuëü²ó¶–—¿ãµº{¿Çûª“ø ÁÑy[lcÒzÿ£çÜÖéýã©ì¿£ÍÞ$“ÜÈ¡¼˜ÕÉ#/ Ã\Cû¹èØVcõõ”¢Þf€€¢ó$ˆweF}Úë#7Ãiö®×ÏßùYõC­AÜ>ïhOÝãV`}]£Nÿ~#7N=­_WÃócÝ£xŸ¬ZÌÛ<]c¶ì½Øý‡âGeúœ•'Ó«V…Õ¯êÕ?œÔ…ס—ñ^äNâƒGO]ŽÏŽ‘âîøgÕÓûuÜ0ýÝ¿#/÷¸r±ãÇž~!úÂ…ËpémŸdÏuÎþTgëÓºˆƒüWè§ïÍ&ÿò’ÄÏœ~×òüð§Mº~ª¶diú¸µnüýWûìƒo¡.ã|·þŒÜ1vÍQì[ž3ùÐy>5«“Z|có°Py?±ãâÔ  Gï×òôówðæâÇìû±/LLjxWsR!ªÒ#9>r¹ ñÁÀvŠ?ŒÄm{÷pjù„!P„DE2zïÈ&ôi¢P$.#7ý“[ ìñÓ³íȃ§¹x‹¶žnì‘æݱ_Á¸»|¶wr.ŽW~sßY“%úOŠvÓÇ4Qô‚<Ë÷ádhHÜ<}ð§Æª1Ó‡„Å÷}{Ý}8õr¤u?|F¶ > aQO^‰aP¦gyT¬¾zÆ«íQƒ‚ùëñŽª¨i Ñ0+t„»Îô—ÓÄ4v\¿Ñ¦,}¾'& m ø2™ÖWt®gV#9`ú&µéË“\ëã7rû®/vyáN›¹ùpäJ†;TˆŽ¶`4¾»c€ƒ×Šëäû¹(—B©Ÿ-E›×‹±"áꙜ % ‚^壤oÖD>´ÝøñÓ»ºCËM_/#/œF˜¿ÕÃõ =½Ú¡Èa4ÿkúœ rZéïÅø€€*+Ü ¼ŽYƒ^2¥hÔH¹‡D—”«‹úräuÕÁº6ûë_GËë‡ã(§ÝÚwØÎæs‡ ðÃÑš ÿ)Á3EÄðnîZè¶Mkãó"µ8ŸõW|k^;v}î1Õúvš“.„íç†Mö?ˆí虲aŽn¶Je%²Þ‰uRº\9¥ Œ™Õ©hÓy'îõ¼iÆ»“M-Ñ'K)$ðe· ºµ Èg¨<vñe¦ÄàF‰cŽ‰Åâ*á£ÏGácwÄiøE^9L4ÞG» ßo¸=3‚H!%'q½Sœ„žÍñá@;Ên;€®±WEÌ·¸1½×3§dE\ýÜ“åL<^q°Å0å©ñLé?—£[kaå<Žòóí]¡Æ+úù=-„=ëòf›ZîKôùïóJ'¨¥1I'f×Ñþ¼Pú0é|ìd);IíŒn}–¾ê#e€NNÒêÙéË;Åü_—®ƒG¨`À Ðo’õ=‡ô1$«b1سJåù²U)ËÄ£}ø‡TAì’žQò|¾‘ßzÆ#/åË—´ÆÂøëoŒçþ'ÌFÑçdùQʇø8fç9œå%%†d&2Á¨9#ƒÂŒŸo¥EkPa¥Pm±R8‚<RŠ”I»b4CC˜òU UiAÆàQQ;Ÿö´»‹!Y«»”Õ™fj££B!Á´ŽÅ-ŽÀ¦°Aȱ¬a¦HSjÈš¡#9H¥¬VÁ•”Õ"4#7Ñ^›dÓ´ï‚aX,™ˆdX¤‚éú´·‹¦¡‡#ÁÉ#ohµW}uRŽ#7§XŸ×ú¯u½ò}?/áλ6ÎÂPP[ÿ§w]ZOÜCOþâêœM¨H_鶼`ˆ#9·Ë#9Öfvç¯b¤,;Œ.EÚL‡¢E(ïOû¾;ÿcÜþ?Ý?rÑ FÀçáÄò…E4­¢cR"GGAP#5˜»hZMê d)TI‘²Õ¨,M±¦Ù…¤’© ÿÚM¡°w‹~=?—äžßßí^¼•ß6/—+Ö†½iôOŽ½“ê8`ÈßÛ¯*áœsx¸k§a¶ÝRÊsÊÝ•ÙŸ.û<ݯþJì§/²ºµ~ݾ­‚^AçU³ôþ>p/CÛÏÏ˯Ö;à›ÄñNÏÕüo}¹Ùóaøå#ü<Ð"à!«VÇ}·çõé1‹ñ{<í;-±f×–Ù‡É=±Ð8yÀäÛ¤j#7xñZ.(ÃGg‰¡± ’$ƒŸS¾²ìlîžï‡ñüWëÛ·V¿gˆ£-BUå-¼qäp  ÕTÛðñp´êõóŠcöÂÎú:ò‡N ÂuþÚ»û\Ž.s™îWIÍ`ahaÙ×Ót9—^4#9›·S¾àÞï¿«g—oñ·g&»¹ §Ü‰¿+?lþý=óÉdÂþؾзùÂ? ;X#9ªŸPB³¤(z·ýAÁšp?¦)á./ðzúmŒMµäb·;Ö¡Š® *ÚQjק|—ÒĨֈheƒÂ#9³Ý-j²ÉY‚–()Ãf¹³m¶!¸láµB ·ß#76öc‰„áQ7¸+F'h4¡ qMˆ4¯»Î\Ë¥AU$’̪ªÖö(ú ‘–à- ¤¥‰(Xž~ÂB>â‡Óüç!Èú¥ù|ËÊ5ÈCåõœ¼]#9•-Ós˜ù·"&ÂI$#9Oä¢Æ…Pª»Ã´÷°múFÉH<9Q"#=~ ÒñÎ@t%CL©QH2t50î¨rDVbä¿#9˜ªïsÉ&Ñ!/p§NÍš¾ääŽ/\Ì»3æDþ®¾¹ßñüj5#’+B#7þØŸ#9Dæ­þiŽ±¦Ú¤ld„q",CQ/èb¶?åeÓy¶‰ytl¨ªB‚YQKÅ‘®·Ïì—òù2øü¶|=c¯ïöxÝ0«‡qÝÃîû¿·OÓ&ƒé[X€ #‹c=zâÃÔ™"+˜æQeû(­¿A1²aˆÁÐá#ipjLo#‘ 0Õ-³#7ÍT)8#9æX "Ôùé¦=e÷QVƈSƒ#JR0Îi§IpE30ËB«¹j412ŠÔX]Æk¥¥æ^ÜŒMu–åCÝ7ˆÌy#9‹FC•˜–6ËZ@öíMŸa##7i¨Ö¬"}‹S"%›·8Æ*°c‘“³]Ÿ(æ-n9ˆ:£UhoM¾ÃZerÌ­”µŽ–DÈu²¸Ù¤DQ63#9ÑÊÀÃD#M£aË(gxmbÑØÍ©¬Eé#7Ðá1¶“­¡×l°lÔ݃0!h¶eÛJ˜£(ÿãÿm¦ì}0ÌsJêm¶Ómæ ²#7³Åà w$ºj´3,!Å$Cas(8ðÅÊ&Cœà‘Ò§“|ýÆ~\r~ßã"½A‰§ƒðûîÝÍÌø¸Cpï½uxÇÛ¹¦¤‚,ªèòÐ<(!Â#/‡‹1¦È&^së³ë2›˜pÃúÍzƒP®bïíçAÍ4#/Ãìá>C²ìtÎiéã¨fièö}GÆ:gžÝ\Úýt§H'X)ØŽ Fg¨p{‹‹•Š$–AbŒX°´ª©øÖʪ `ÓŒÕw†=øeŒÖ‘¹"æã Ë‹J1¤J>ÉðÐ`ªÉ.HŽ)FD‰©…ã~Û¦Zä…<`¼q‘–`_¿z3¡²OVï3½Œ[P6qzM7§B‡v<„W¹âôi±³@KE.–ˆ4Ní ÔÈ a#®ÓŒÅâ몭B!S§/íü²r×k»¤kmó…2ËPZ^å½®Š8†Cójáýïyý}wíõòÏ—|‡Ÿ]ñuie«¸dŸ.#×ýž(Ó²Œ`Š‡—”0n€äV(c§ÓnÏ®J.ZVƒ#qn¢1ÑÚ@ùíp™s,d)"ÀPF#9ýµFPÒ#7P(±ƒ¹TÆç 0U0$h}¤u·}j£);Bº.¬ƒú²–‘¸£ÁÚ9ĤiØòªŠF ¬jØ´Õ#G·žLî!LÊÓDº Úk:öÌâ(7ߘ-œÖs+XpJ1•ØP„E“XJeI.¤kL[ñ¥bÀ#Q#)_*rÚ®ÈuT4‹I¼‹õ²¹ºTј5Á-ŽÕFHq,7x÷Ám.üQrë$™#9:H8i 9Àê7W€ôÓ´±p¡¸hˬ†lcpÜHˆ¯fƒF¡§ëLpñÀÃN3R3õB¶ŽÆð:.°«§0+r¸¬#7”#ȤË$c­VC!*“v¶­À+ÙßkP·b{£†Ì1¼Lf&h'ç`Ÿ~:@i˧¥Ôm?Ú"v«Ös5‡MòƘþœË>Û¡~x—êõ#—ÀÎF£#7Å:÷‡¤™íÒƒ6C`Ð>âʯ Íáh0sgTïhv-ª¨VûÈÖÅ!'dî¶4ÛxU÷Ú`ÊbÀ9roC³|¼`/#9«!Ñ¢-´‹%×,c$“V/•Ü–ãU×>–m¶1Â(»†ó¿;èÍK#ÞY$W³Å×á£3lcâÆÕh“™ÎÍÃxC"mh1•É9:zÀÞ—he¼š7‰š5íäÛƲÂÆúòœßlé`A»Ð¸ÍYÐåãK‘*.q̺JAbÅ>u`ç5W¶¬ÍíË[mýZV¿3ôLЛV‚‚gaí1fáÍÆè8|K"ŸsmŒÓ™¶¡0ÚÀìé6ÎÆâ0¶×&Ãu˜Bb““b8;OÄA—f„á—`ÁP`¾#â<¬JŽðqÆÞRà&IaçxÛ%Õ½õglŒá¶`ÜöpòÌA£ncTaÃF472n}Èãa™#9rú’7˜fð–ï[”/^»íy7hÇXÖ·}^BÞD݈&Ç}¼—`ÙnoËá ¨Œ\^vª»É•P\Î{báif¥jUóœôÓ@Sº¹Üí¦8\Aƒ%¾ü˜g̙̈!ÜÚ9—„Êå(·‹|âÙ7#7­t®‰¢>’N\5¸ÒÜ#9#»ÁGV]WÁk¾"ùÚwT%ÜQ¶ÔvtwD“y‰d¬w#9Î6#99¼·c\&ã2Š]qq¬û¨5‹#7ÙŒHm¶÷:1ìºEjÇhDèÅ7]]g2rgfÊ™CKW#X†cƆj}áá6¢µE“†7Ea’3„ç&5¡SeÈÍõrIÎÙ E!-Þä­×l #9Ó¨cÇ.Ûl–NZA<“kRhA†ÓÌØæ2û=Ç+ß ÓyO¿LêØ66í(Mö_)ðŒ ÝÐÐ!(dwç¯Ú|mÝ1I”O*m££•i*x‡T9‡z/8òÅwWÂ^ŸNe±ÀÔì,óG"qF"è÷¢1Œ!ˆÉUùâ•5[mÐÒWþ»Œ‰8œí3Ê"ë§óÑ;²~攘ç¾™§ì*„ôïýWËmˆºunLLÌ8òÉÞÿÕuÂèâˆÂÎ\¥$í}”¨Ì:…8žÂOKCé'e§fˆ"&tUN—Ž³',7M·ü=¬àÞOÒgâô-´šKyÀh§¥N2ƒ‰õÍ\¢ 8Ð#ÑRßj‰ÁàDýÞâѹFìœuw¾Šáé[[ã>šð ø2Ý䀹Ðißè”Æ´’ð$Ë¡pCÌ¡áÉ¥®Dîê’Iñ^Õ9‚yÐq’ù†hÈ]t1†"ÛFY·×ðè>6ç”ûñýëãË*ø¶µ2g‰lœ¡bÛ#/Ф¸#ÀRže–:»ôþ{?ÑÙÂìÓ NÈ牢 àžNWÁîÜø€/Û|äÇÓ—6CþñíÍÌþ{ãc†³¢àk#7wiIø.á& ‰?¬úÉþ»íSYðƬðw9*=Ád‹*?¨Ñ½<†š#7F}aËÞè‹d#9ñÎÀ;?@Qƒ­MÈSTu‡FâqAØ&&÷…Ó÷¼Ðwsà/#7¼.ŸˆýÐD|òEÊÉ´àøÔÔ ÄÛ0L61W@;!JU#Þ~:ÌýOèþéhÊvs—wú3ç -èpÈ—¢¦Š%à2_Àãɘª|¦7GÓ(~Ç<#7‘JJÙ,»Ë—!B#96˜%Xa-¯4¸ ˜ÃXE_S]qŠ?O)W E#7ƒÞ¾yãóË Â9ªŠ·‘Õœwm’˜—#9‡39Y)(ÁÌ#/ýÝ1«3\H’*cdþ#7ŠÝVŠ¡Ý¦¯Â‹@˜V¬´ÐD2l©dè—÷ÅB|Û#9|´xÜÅy|#£6¿åxÕð¢¤ò­TôumŸB—uú‰=L:otß¾Ó:#¤ð©b'2™Z‘L™‡@j¦ß¢Av¾zb$)¥j"¼]Jª`Îq%[Ž“¡î2»¨ƒïô…îÆQ92eæ#9’„Ù̩µ†í6ø}×-´óàÎõ‡Ç»–QÔ|gWÝ;ɯp=2ROiÒ÷ ³a9œ"Dôc¾h>Î5¡=H^Õ#9E€bèhC>ÛšÞ}+·IÎÏáfíM$Ö‘OfÞâ7b‡Åþñm=㬘âË»•ê<ŠniåØf¥#`ö¨®•ê›MdŸâ§®BB¦|DŠJg­ÙvÕ{NüöÃÙÒM·ÞŸ š<1JÇŽõÆÇÎoê—˧“®ƒŽvB†Cní}Ji“ƒDˆZ-Ý @d¹­1øñÞ÷T0Œ-C`fW0¡`БéÐv9DàŒ£…#/Ÿà¸#7Ìžø2e»N±|¨çw#7ÝØbÛœ5ng53«T¬æî–ÆueXa„zm‡>¸© L:- !ûµÁ‹"#Ž¼ü8#7{éúôÑÑbÄQ&–OÍnÙ¶8ÿr2¦rØ>ÍßÂôÄfBÂeâ-3ÍJ¼#7{R{¬²ê¡gh§—­žF¥ˆT©]R÷¢çäÇ=¢@Ö4Ý ®¹3 "äx`71–TJ#9ðM›ž;àâ3"èœJ¡Ñ ÜD(]uG»n¯å¹5yž#0¼˜¿Æù|#Ë›‹<ߊ°àíÕ; uEÛ»` 'ÎP‡°ÓVánL(€$ı#ä²Õ’c0$J‰ò<íL-Ó½L×·&”Ä\ËRæ‘òãêÜGƒ“—êz»y&ÂESÀ­dJ¸U,•>¼<Ö"ý,÷3QúŠÿá6nêN‰tL\ èªžm@£ïŠÁF<ÞE#9n~¹ÌmÀàÕ©°øuša¡çcˆ¾ìçžh¨=|?|$i¤ÑEdD„Ô$ý1¬s{)4Γ#/‘7%D%FAÚa ¤9[ô⠘Šç,Ó?ÐW8“êåàd¹Ý!,Ú(-|€;xÒn“,%ÀÜP Âv½E´-=e"x­šÛ×ÃÆÑ(ûˈë´;Í-!‹^b{‚sƒÞ8œbùÕ"µâFÍ»úì²éNw*hPØáÎt!'áæYCÆÞ6‘œVÑ®4]¾ì1ãn-Rg·>7t‘¹uíΛ&^…ëÍȳP;ñÃÑE ö»>huZ·†IÄ~5—½Ž¶ßÎŒuxÙºΖðÀýšÎ“Q7s¾¿7⛪àáÎd„#9QÐÝ4·¹°ï˜Ó»…‹Z½ ¿Mšx8|ÈÿdÒ)Ì^0Ÿo¾û||£=ûQÝÊt–Ú÷½®;”fò^²©Êvç,G¥Üçïôß…Fûz7ómmÐHæ™ù·9Þ ÅŠ-íš$¢xxOΑï*MF¢Ðð¢9„¼ìÌ`,m:TiÛðiHòAMü+™®ƒl#«bÏ?†æ#9åzYÇ»ïET`Ù¾Ñä«u#›N'æP¾:±¶¡CŸz1™aòZnpg}›ž½ó®žÓø>pE0§h¨©„ˆì‹½¶ódSŠä‡—ðœ+›,3ÏBÏÓ¦óúI{ýËÔ#c‚6ÅÌ EyNÂàJœ¨ÊA`Ò£"¥Ä»R) -Eú¥Œ¢%yyú¶wÌÈšY<;ö‘áÎg,[Xi²Éü&|3MáU£Ã]æ™u»Þ@¡òE(‚:åeX¤wD³#KmÍícFQ "1)­áMþ?LC&7(eò–gYeÕµöÜ°dQê;Æ5]~%¶è}ÃõlC¯ƒy ¡¯°]]C»ár‡Ø€Ë˜°¨u™2çÇ,Ü€DUËÂÍsY±-ylÎ(÷&{éÜH>;Þb¯o‘Œí»Á|èÛ8ÞéPø7S L ·ñÕáƒÒ •î{ˆy=18ôN,¦sÇ¿´“€\G~$BM :<e-O†°Z–#4mq-MŸÐ§ïÚ>8:o&?t¸­ÿàUùkƒƒÞ¡Ü¡GàQDy¿9³ëµiªÌuãm#/âTjWŽÇþñ*B#ÒÓ\nÕe+òÒ±.Vk•m)c¾ÅkagY­b5,#7ó{K7[êhJÜ8ʸ>ÍÑ €ˆ!…Rõ£i¸ @Š¨Xïxºoç[YÜÚmª#78UÔ/sµ£7æ^*$µ»’rz¬žOl¶b,ÈpQ#9µ]†/lµà<»Db#7(-i¼\ÙrÉ¢«“ ‹E!E‰û^ŽŽØàìŸ#9e!O,u¯äF©ócÁõ  £â÷É'nàÚ#ŠÏ…aÍŽÁÓ˜{ð·%N讜p²0“p8žXf¬.ªÆ.+…ú¬±b§ŸeŽ¿E’¶nP´–+ Y–M6Íw?;ƒKô®™Úöƺ¸gÅú«ÁµRÆ Å%w':ŽDV-æå˜L-—¾©¨]ýVlºßÂ"ü±œŸ¼÷Î:Ò*xÔyXþÏ:Áèr]ÚjÛtë‹Þã"V›‹tº )~pÙ­vÊRró¶œvÅÑÛ,(Là¶âÅàç«?¿:ãV˜,Wƒ!?Á`É‹#9à³­$Ä*¿®½óÁr^(é¨g·0Ÿ·²#¢=°Ý2údóµÒNõ!o~_±õ}.WIé¤nÖXmxÛ®fiYÝ瑪äƒï6]«s4u,sÁylü1„4pº"oFN½(ëRð¼‡ß—æ h¥&²v]‡Þ6ÆÐÛýÖW2oK9ÉTÐÛÀûù>«2xõùttØÉA²?WFï€c”Eþ)Zíó/ÙŸ“¾CYÞb#7õ[®L¶‡¼p'8JÞ¾í·³ju³¾´Î±{ÌËw÷q=üs¼ç¹©-]4#9+Q±Ò:™2ƒÐò37>æóÚ¶¥ª,‹Ü8¨ê¬ؼ^¾'‡WªÇcŸ•uIõ"Š1ž$$ù—%±îÅV>X†möZ4ƒÃJ’‡Vš ï¢;#9Cå·sádmZû¬6^Õ¯Ç06SÛ­åÎ*™4úóŠÝMÙBʇl—}%thÈ'UV7U€Òo)ª<¤`ðn}—=æÂ÷#9Û£øÓ}^Dê¸,´tÍÀºYÒÒ×àèóAÂ`¡ êr¹ƒ2w\ùë]A|Š%BVëç]ºZî€/ªït¿cÁ¥Ì8ñ+èÒ¥•kŒ­†=n•^-sMí»MÂPËc›EVÕe½ÏrÝW¶ Ы™eFè3åw¢Ës`w#7/”ö| Ú9Û¬Æ`ÝåmÏ'>Õõ#b§F5Lv헌ݠÝT¢¬øé6O~–‰êÆ–*õ?áÅR¨R<„L¦šN•¶½ó6–®ï¨Û»öc_l™ÚuÍÍ¿Å`´Å£œŸ'Í,Û¢"[XdóœMu„= Ç6¨®‹2±íª9<¥­ž”xHž' E_7oÊ7+3­Óo9g`ÀT8;:°•’¶#/\Ý1}s› IñZŠº">±M†BW¡I ›ÈáZ™[Bîw]Jìp|–JV²sÝ:úŒãRñ…¤q¹n›"ó›EˤZ‚@Ä4ÎzoÖ&Õ²šØpt´wçs¥¸jt ÖN—lºº\µsÝ0ÒÂ(±†¤ËU«… ˆ£ËjÛ=g8«"]üq´3|“C 4ýsçÇc`†Ši³ósØM)"$Âdrƒ½Ï“ËùEô‹=¿Sç³¥Ÿš×£É2Q(G!mðÕkgŽºAÜ2­¯ˆ[ V°, m¦o{›{š×ò›¹!º Òè½÷í¹öBó>3Õ°tßÚT3–lå âMi)æéðY,ƒ>èÑ7ge£}-Ù[#†œÝ{Ü¥Í榺ÊÞ¶~kê¼½5ê£:·~Uämòïbí!š‚»ÚÌã²bt„c(ºÅ¼×›ôÓ#dÕb±ÛØ8îÔægÒvÏ6L¼yÔ™:|q&¬æ1Ööã+TkôRwÙ¡çn¸r–#7\q!íæûÞ9ñQaÚu^ÕSÇä÷{¢m×ëõóóQ¦+sxöêJ¦àå3º8#9cÕ)ÚÒ&Îì-bÆ æÖuimU–U!’”fCÖW%DsS™Â’Ò7÷/¾ìÆ-”A9°ãõ梩uýÝb¨wT¦D7·i‚§¢V–±—Iº¯H[ÙX’|ÊvÃ[Ü%`ÛIEØFœ¤qxp#ÃÌ´"‘Ö fŽàEö¹ BŽfH9S»â»jÚUõ‡:§3ùâãÃÀ“…}3‡èYyÓáeo3uG¹êtø½ŽÇÃøïïÞzk{̹\dï ×íµ,äÑÆ{>k×&úôÇQ];Íïí·_‹ŽÞ¾±©38z†iGïw ݼ´ÞÎ%y™ëÌ̦ðàåf¼p/ô\uŸ&Æ”úøà:ôÔg´« E6\-|åe'¼e!; ÂÛÝMÏU6FZ¯5q‹ú¡ú<¡l?ŽO%Þžµžø7ÅbÏ5#¦ ‰†Þ"JÖö³í¬6}(°Ñíð|*ã¼j¥úÅ¥ê&”ªÞ×E…¼)³Ÿ»‘ÿG¿±ërcŽ³¢l:Ù./É͇]!K£ªÅb¨NÈ#7.ÁR[cŸ©²þˆ5ïË•æ(H\‰7°Q©1Q¢¢ÑWÌÃiÝÎo¦MîaXiûIàdñŶ^Sq÷'`c·åp1Î3Œ —£ûuj“;gRÔ”Fͱs})¤4‘Ë ,E4¹œ…Ï|匱jUL$°äÝN°RcÂv¹.‚¼rŠÛ‹ÃôõµgSã”DM¤bå#9w4½X”ÞÂ#°¸wà ×CO6\ùÅ „°tì+~ÕŒï¹TtôÃæ"—ŒÅ†øEŽÏ4#9Q#/Û5t\]‹öÉÅ”…8Åšäqo4Ÿ1l­\0ÔæN½ö:W•ÐNê#/xŽÒ4žsÁ¬¾Ë:£°€àBJ(fîî­ù7FµÃt¯yjHLVÖš³ù_aî 2 7¹uXòØà"ú=rÇv…Óðšloós`ÕKJ%á‡h#/€ã årÅF´“úš¥â=*mc·yíqU)îýyî+N}¾ÃÉâvÃLó÷,çþO8ÔCëÜ¢}m]y™Ò¤eþõûïÛ/ã—œ@µÞ7"U™4çoÎWdUÕx9ÌŽš†˜Î‘!×Õ±ám_€£ƒÁicƒœñ‘ÖõÓÆJ6Ê}ÓZMMU¿šë6ü›=£ÉüwÇ9èþ+ÐM¾Ÿ®fq£JmÊ7˜!ÌÑÈQ %bF¡´MÂê½mJV)5[ó[#AGOn¬æÂãhÒfHFgi¾?üŽÜä>›ßWV`Ûñ¤9ïZ£¢i«W#ø+ë7¬MÛµÃÑŠíW¹åMéñÑ·FÙ e·GÏy®“E£FBfFyëUÇ­áÝ#9iœMçsÁá®'¾Æ)›ߪH\Û#/(è¦Â°ë¾{ö AÆ·a~¥Æ)³CÖ:\ñLÔ]9½Ë£NV芛\Xº5%ã“=¢âŸF‰Ü·(\dÂ#ÎúÆP$‘¾_•Ÿ…ŸIŠþøþ¯ŒrMº¿o(#9ñûâo9›–òh3}ægÚð¾æ¶ÇŸ›®Éˆ´:J—˜0šýÞÙŸ¼çh¼T’|QÌyÀou Û¡×űïxG™lÔz;_Ï“¿<ÝMŸNJƒtn¬ú|ñÄ÷ ŦùÁ:í^]ïÛÕèÕ(s[E®ÉÏ„Ô¤‰o?=v÷ác0éÁ×»w”r9ð>·G:íën’<$=¹Õ@–ª‡JPŸ«ü'³VðÇ‚aÓmB{1ü-j›"^ç(F„ðvoú<ô¿IŽ`ú-F‹)S8»|Îwá¡ÉnÂÇ þ9 Ç$a˜hÍ€5ó¬UåçÜsÙÖ¶º¦Fywµ]#9Ç97”ùx-§uL>û‡™,ÇQeÓ¤J7ërý*â J—£×—àŠ’GË—Õý7Ç^WÙóŸîêW— n‚ïÌ}Î9ߦ¡NáO®öÖ1KL‡j‡W6*÷¹­Ò'¾~£ƒFávØ2eæOf§lWJjd±¤Uì2+R2V ‘Mø?R9¡—FëQ3@Óáß>'w`¤:„2ðÇ0c¯2áæÕ¯.ñ±GŽÓ½W•>]S:n&„#/V!zêÄ[Â#7ë …k½h7nÚô\ðý|º¶ßz¯#7¹av¦ž¥AD'aкJ#7dj/dRÓµ®#_Åàùr/`ÙùCÁÒae´uÒßH@h#/yag¡TÑS®¡¤’Ñn[¦÷¦ßF6#7zr? °|y}GáÈZneižŠà…!nÿ–÷U=½nâ¶4‡ù/þJŠµNÛ/žáÖºc%R:­ñ3´)>íiÛJŽµL9Çô¬#9@îZ%€¡š‹ jv‹^?VGÚ{ïE¦å²Š ü_±Üü×ÈñË©36y=}ðöØüT-š Êè2QÎíªoŸž8ýçã~ÊÓ¤§0-á¤|®‰¥ZHg§?3ÇøOŽ×&V¨ân–#7£Í-ͤh—‰µ*ûƒ¤Â“†‡G×±$È~¾ÊÔŸNBeãnõ¸Fu%ÍI$jý~‡r/˜iÌËݧ„Ð@xŠý¸gP=þ|nü»Ç‚x¢·—¯õÏ–Rµ|4aÈBŽR”DæHªR £ÜŽa¥èñó/¬ G1¹?/¤9„t„ÜPgM6Cæ#9Seò=GnŽ¨×{ã‹ ñs¹#9p AäÇà×…úÅ”åŸÆiùþEr*"üjû~9ÕÈf•×ÀïùÓ–b»vç÷íþGaûã0&Ã2¤´ƒc_º[ì6WêôX”‹DBÄ´Ò)H†œãÓoC÷}ýÇaœÛ/Jû¢¨ð˜}ÆhX‡îçAÔ|JÿoÕgš,cÖfk8gž¹ßÓ&ùóÛy?½òeе~ƒ\¹yÎä<*ª(&˜À;ÄÜ]ªvYî/[®µ'£ „‡iÄþ‘ÒalîÈtÆgØÌyÓµgÎêì´Zy£#û©†ÍƒèðBW.¡ÏÞϳ}Š,?AÚ°o'”#î#9(.@Ÿ-ðvâ‡è®/Íýw‚sfÑᨣ0åšÓšôþW÷)Nd•AÖfBUQnÁ7þª‹<øâQA±ÊÞÄ@£6…°¿àVõ÷×ø‚ò×O‹*Hœ“’Ê=D-òògv°ík夙 õñX±–.E‚ôb Žý[Ç+õèàºí¬>p·pFzò#7§ø0·ñô2}ßH6:)鱸:Øè©bK»¡)±v´‡6æõ`‘p‰Fs0õô0¤|P˜sýQœçÔ&—N>»vˆ—‹(ô6© ¾SÞÏ908’'ìýÑÁucûTCH:—v±¶ÅÉlÈúîˆk“©ÐCÖõ4Ÿß¿/{í?~¢D¥Å6­V*UY—¼âàAmâîú×î×îüIW3Áq*Ѓ{û/¼j!²ÊÝ/À§bõ¡P”[6£«Sœ_#7Á‚ÿCK£µÛ$¹ð€èWVyìpŠ-8{ÑOF÷`Ptëç«,kf8»µÀv"€|PÒÙ€ÏìÓ”H—~½=1à³'Î ¤ZÓ'qÃñî™CYœAÃÜi”Áiµ­L· ü(&IbÕ1–œXX›LO˜Îqá­±¶bC,ÇA3#7Êf<±)ßî>ãŒÏTV=ïö_Eç3b€ ˜C½w0çY¨YÛ Nº/l_«Výwkª6„Pòt5gÝ–2&ü³ÒPËÊ, @ùqáÅð÷ã ï÷õ°%#/¶Qw'[ùÀ ³!•º8õ_åwL°YÙîÄìÍg=ÿ;Pñ$™fÈt{?šµ קÉSâ‘'¯Nzâf°Œ4>~"Õ9HѺ±µ,ˆF"%ÃvèÝ(°\Š0¹ï³Æô?¢ÄÂC`(-3¿ËåûÇM£ÐÍ÷ q¯¨Æ4|Lú\Õ7HqHl’#9¡6:ÕQDQzÛG0RŒÏ£ùÀñqßµÂîœS—̪~¶Î}ºYõý“M#/ïd-.WTð1êDMزëç¸*¡ F:"ÁÍÃ¥žÛX€=6hñ~ž^:;‰Œ#Ï)S‰8¨àSÙà©|è;ÈÏþ,ë ¼åôâû#7ÍÔþ:·Ü7¿Ýü•aÖNQż¿y˃2}}#9o#7GÍäNýWIåæþãæwƒ¦/³9 "ój€Ä¥Í7Ž1t–5Œƒ.fÉ]S¢h—IÔ|Go_€ÎÁ¨;$ï¿™å‹bÏßGlgÝ!MÙmó= ] ˜Uåäéadmä#9u#7xÌX“óÝd.g”©|›™R˜#7 ½" n [!-l)‚a7züJ®X'?׬ÞnE“?„ …"©ipûÝÐxò×iÊë„òZÓ“ƒîTÆií’Ï(⤂Þ<Õ]1"Ñߎ’' ¥íl™…ª”D»óE«³·_˜Sžîƒ(~„„¬-r!e½Üg=0^2VÉOMô¾*ãcåˆnG½»cçÈÝI—5ÈÁqäwgl „õ”H²opxEý+Ù7G³lÙü­ *ý¥5‚W”A«#7á]sÜ‚ˆ;`œ§Åu8 sqB@$¼te–é`#È´XýÜÞÍóƒ~:†Rª2ÍРCàÈQ׶”z‰A–óKl„!…/†Êi X :6î[šò;¦óú, „a•KË‘Ý”_eåGºÎÈnØ<ïó›ÜR£Ö<×–ýÉ~[÷ƃ2Úáøù܈J‹…ã—" Q}Ù…È’Zäµ×ò‹ØAáûðà¼ÓÛÕﲡýnÄS‹ß†Ÿ–X›ŠJKDHKù‘]Ü°¼S먦¥èæA;Ö6ãÛÁÛF`uÓå‰#7*XìíTî&Û>Ú“H´ÍoQŠÏË`·ê;ñÊ÷³ ‹ÓCH1˜ÒŒ‰rT…ŒðggL@àˆá2öMƒ8íúÍ€í¬a®îUÍú.Rªá–q`¢7%‚¼!*ÁÄ828âyBàqÖ8vpºÆj›yùÀ™[W—äÜ€mß1>s?Ñe㾚–8é¯:K·´q`\ÀÛ%$‹d¡æÞУš¹Ÿ"ˆ1Þªè¯g/±Œ`é'xÖ ©žnâðˆHTz•DÜ{Â}l™Ýg†ÅÛ#9T>=ÕÑãà?™ò¾=zú’ô\×™-ænnëJ†A–B ŒˆÐ«ÊáÀlÐ¥ òý7ã`„Ow¶£)êäe›Ni‘vÇëÖpaÑ€[…hó§‡T5aÙëÆ; ÷mNÉë1áÚ_™fGÓ?hô­í‹¦Ú?T¼%ʨ»Vãè;Æ.0åß6Ò°»L6¥Ï^Ü\UU~~aDÙbëyÄ8é'È.EÝ›8pŒò}£l4Ç•'Ç€Ö^KdJgÏo)ìð_Ur؈j—v”Þ±0Âot“vùRO›j“¥AoG6-ò7õ¸8ÓJ¶ æp%³{-§u0·HmÈs°O€Ô\&ÌÆ“6]¬2¼Ìnši²ÙF(MÛbúÿrDd )$^ˆçQ:Ò².¦3˜ºPA\ò•}`Q¶”ÿðd¾ $ù#79ð{&Íkœâš¿¦‚|Póññ‰b6,âDBÕË9¢#9êÞ§.Øõê†ï#¦ƒß‘™}Öñ;;é³0&w{ön2¬]Í1ØUß"A´åv&L’2Ò‹I¦ÆÚtí×åÄtç)†¬ëÈß™¶â-=¸ /’ûÅ&é©Ç†;9ϧVñ&dvC®ù¥&%=„LÕ®¢ l%ÐÉCPö|ۘב„?œ…s#ëxhM\~v»uÆþIÝkõ÷çž·|UŸõÏß*\C½g£ˆŸM„Õ&ŸÇþ—›ñ7|ñ:æ£h.³”D1¡ ‘Ç1úbÇ­k44~ØÃP¤’PÕ÷~¾¾…Ú¥R¥8¨#/—êÚny‹›™WîƒùÒ·»ü1UTæÀM¾ƒï"jýŸi²:üh*¿ÊçÇxî#!þŸ¿š)=‚z¾¿ëîݧÌ?ÃÈ0ŸR}|/>ü±QU`CñAÝ¡ ÜH»·öå•Å÷Oö>ÏÁ>l#/˜ø#/ø½^Æxæ õ2¦ uJ\eñ#/“àÖ¨Yß Þ©yIwo¶{ùˆ×:¹ËÍK®p#9RÑžíM˜b±…B}[Yä„9ã&;(ÉâÊ@‚SW Eä¢9'fÌzRhR©”ÒA+ÕVÌ¿P‰‡ðý<Û1%C¤Ië÷ùgqËÜkEõõXrº'P½¨øFúTÑÓwz¢›f#[5R°ÈŒbY·™1Ž \KLùÓÊ?Tª+Šj½T/x`È,Ì#7:]ÌMÉíÚC —¤øwZ÷…ê\õ°Á“ƒIiB®¼l˜˜öÉAÊBõ›w¾Æ¾2”zÑèµ²ÿSÝ€#aÀ¸å}0RøÜ:ò<Ý~oÙ´|Iu£p4r·J¢„·ÓŠ–)DyBÛìpM¨H™È7fY'0Q0ô.°~YŸ¿øÿK´ÏŸî¹¡Ë׫{ýð-#/‚:Ã0#90À£ Æs‚¤¿?Éà!õ¨Pû²`Y•ª®òAhB'/AADñ°#Å1ú¸¿±ð#9`ÓŠøËä̈mÈr¹£Ì1#/âiˆ¼¤5îˆ5H¦‘ö»KÓ”£[&ð°#/d3´ q^ÈÐ2õv@øø‰°*i”@“µÒ:ùçé…tͦ&Ž)Bl=ŒG’ŽÎú6@”…&&n#7Œ'ë᡹Ü7Fð¡ÑÙ:&»Eî–É®DÂQ’‹hb©×m¤8”ý‡$E8 p ÷hˆ*gµ#9Æ}G¤~Õ‡éTÿ×îöoÄ{#9WV@5Œ EU.,郙١ø*ø×Ñ1@¡Э,a0¡ÈÀûˆ?A•#½W+&!Rg¶Í̆‚r#9BpeO„@O*øMáǪþ·õB'qPwr•»M™‰¨Êínqu “»ø¢ŠsëCíå¬b³¨ïHJïPSïuOh<ÿG60,¾²JÓ[‘ý|3M†cnh?½ÖÝ+Ÿ2GG&ôÓ÷Ðîä¢0ñ$›ŒÁhP½QŒŠ['m’ï9h)Œ¡Ï žÛh‰öòá¥ár%32•åA4°Œ£‚¥Î®Îd7ÔK÷†È¼Ç;÷ߘvD9%ee_Õ%\/j0ïšìu†Ö{%gGê–qQÀ\Õ¡PxÎMŒº(Ë#9Ü‚:JpÅÃ!Äìõa dd‘pô?XåÕCƒ'z3Tj¡”=Où8ôª|šbÃQtAäòƒ«v~‡¤Ã`î؆…oŽÊš+«ï—˜S±D_9'~ej}"°K«‹|ñ<…Ÿå¡œú1ˆ•žŸOS¼X™3áF ×»`M¹Ή➈ù5£"qIb™ óÇN#/:lCB&Õ:Ô&ªÃ0É$Q¨V Ž‚^ùtH›KT‹ ’¡’!#9@ÉKÍ—ëL .ó™w­<[o™K&Œë:)KQåO-ô<§Ð."½:‹:Ô‚t¯¥À¡èÏ×Ç%©öJÇ•N†yO|ÊúìPD4·Œ¦b‡K³6>X­³„(åÛ–°“`fC3H[¹#’Ž-*ÐÒÙ‚=‡nF q!8|ç:Š#9R¨™@°J¢¤Hw^ ëÞè/†t¿rvNÞ wè ¨Å¤))ׇ\™#/FDU†VËËHúh—f:¥Ý.Ì9yOŽJ.",#7eóÈ3×}kS®Ý÷ò¤ÅvrcZM„U<¤x €w‡ŸwË׺7×Ëz“ãß<ì'Ö_‡ Õ# S§>ªß“cX”>uåIiBˤ…A¶#/Yþdøü¹UVu<¼}üH£ÇÀ<7!ÖËã)'kÁ ñúuØ`žIsz8¯Ë·„.É—Щonö¼óAž~Û2ªB¤E¦‹Ô F—ž8XwìoÕ+J îLŽ<;ÜŒ3Ȳøøì½®žˆ¸É =8“¨C©&8wS)Aøž\¶‰¬€u³|¿|ì¿V+‹T'nÇÕ­ôìžýV#9tEMÕ^ y|Q(PUzŒV!TÔeÍuwPg®òn:ìÕwt¤– º™2ñíF§Âú›Þ=¼üÇ]¾ŠGF¥¯Í¨4Á³Ÿ vJLîš]{á³6[½ìÅäû5³r¤NšA|÷vß»XhƒÒJ`Ou¨,ÏLð…Éž È™Ó:!‰H¨¨lõ;h™'tÉÏÜÎéGP';KP¤€Gó Ïfû#ƒËÄ•t0Y·§@–nÍôg}Ÿˆ¶˜*ïf8É7u‘³l¤œ#€ìŸ›c’CôÔáÅÐø`gªåÞA}ÉDØ3rÔñ¾=ýp9²29¦éÐ^㢟Çïõæt91AAÖ#7M˜„ 'ÁÌ46ÞS‡wK8Q3ÂQÜT×÷}ÛúXÖbdú]oﶸÓÄ!Î_•3÷v¹§\B@˜†Âb†—Jw¼y50Ôû?Õ¾Ó¹ºçÂrpôŽ™9sÁ0 ½å€T x!ózvz:zŸ–ε{zºzì~Ư$˜ËÄm4Œ¯y‡ªxYá*ôrÉÎé#r9™dfQyzøv½&fKÆCa‘¤$Œ§®×•âúžv^uqîé‘EC¨d p˜hˇ±òàÏ2MnøoTwÚQ#9ô£&ÉÅtg†‘ýs{C að³Ïåç3ƒ˜ns<1Nþ¼Æçgßm<ÍBå0uCŽþk^ÏoœŒöøÙ:;§‡$Ù²`„³m†šA¦VeÊI­¡&™#/bd`5i"ùœ±@{»\MŒÓÒ‚Ž.Æ0sy¼8Âx2©¥{„=›±>íI9{·9¶úÄNµ°mAK0ÕÙiÚ£%v¹ Ð0‚@ÍXl)ºªõXHv§©t¢@ˆJ+`ï“S³“=0·§8˜ÈâzŒr¢Ž*PP`ª‹ÈÈ¢Î,¢’R ŽõC³†‡„¾¸T:ñô1§ í6k¹ÂNÃ85_:®[ì„^°ã±öÂÞc[—;:~4„0{5ÕmF-“•÷Âo}åº;å-üܧl-{#­3Ü61g3¡·Ž!1À°ÄÛ|#/õ>(-Œgµ–ÝlC§no²…÷ܨQšvW$|˜:†¢ˆPyµ¢¯Ø^!-Å[„XnûÙ÷Ü©È2]¥A4"Òi×&D#JÕÄž†êÙpGù%ybäÑ+À.NœƒÅ‡‘#7'6^žÐ(ØAĈÄ4(ªÐ38J›‰’>*…ZÙh~Ý”1!é§%,¹3¬œ+u˜eµ Ū’ònš#9G#/½½ß‹%wI´T à#/:ÍÎÖ©ÒhzT<,ØYƒzü­`rO‡#4ËŠD¿éç~tvkå’:Áì ô¯¶fIlîg«Z!UHñÃ×M[æ1~zݽ|®›E#7ÂJ ¦/÷m›¬lS¢H Ô[RÂ*´ Ò܇–£wÙˆc `÷¸?z8å²{ ¶d“(>Q©aÐàÙAÁí~Ô*«ºvpLì#7]­ƒ¢³§I‡—õždé·á¶³é´E|üûÑ#aÄÛ‰'õ­º×s+Ñåç¯Îa¬ì”ûžX’3}¼aͦ,âkß^O ö'c×iÈìÞ¯ˆÙï?!;1àÃÍ$(háuÙ&^r˜lI-íÈã-ÓCÂG©!ʉ9´baÕ¡#7d#71írUÔi \’Dí†Q4T>K¯)ª4˜À–™54&¶Äz^Xh½.a¤ÌRû¹ë¹Ó[{<.¡ö›bt$íru2bb ’@¼ÓŒèÍg ÉŒ‚øuüë½ÔYRÖfj|4Sh<9ën·itçèñèäyƒ×@HùT é¡S£ ³nT=P©ÛÍAÉißSÅdDZ{¬æíU?Pí¦Ã'Ú…™ª©ÜÑMEýoŸ^å  m!RÁ¨þE’󢟫™{Yh€œuîÒºD(˜ DåUà5ÛAÑt$QC(|°#/„ò_Ãî|g`TÙ¢!¯•¾L%½Á¼Ž¨t3Ð<'òøgý^òÑÖ)ýS¿„ù9ÁøÙ2‡šOZÈ,†ƒÌhÕŸŽÞ}¹ôé¿œðB퇶QMüíþà*~£g»°wü!ý§Ã šIúDZ³‚‘ Á4}Z‚àÁJÜB¬:ᬦ†„—Ä“#9ßñþù¸lkC÷Øþ8ÿ*}ð$4Ò‡)ér{Õ&z!¡;Îë4Æ=ð$=3žÈJšÕj3‹#9_ÚšAJ=:Ýw͘›m˜êöIáˆ?8O2t hûcÓ™ŠܳS‡h®î££æao2’©Iï}é½®#[Lé;ÓìÜó÷HÙä5õ4Ý‘³q§ 4xRŠ$€"_çö{sþ.{žô{Ø?çܺÞ3÷¿×N‘´™DJoVåÉnO§íÚæ±Â•H™°*#/ …Òù–y\–Üè–Úv3§ó…!¿Z†#9ÓøUÊJºä¡`ìô(õg7Íâ`^ˆAÐØß_íòì?ØÛr¸j«Ž{’#/C^5(r#/#/ÇÛýÞogéþßÛûãüeý†V#7þÿðc,J~.¶{‹ÊÖsœ¶M·¾i0¶¢.}gâ¬ÃJUaz½Z³sž¤ö#7œûuƒìDD( /øP$4$ '#9п¿ÏÇâuãeº¥ç¢‚S1'Ù­öSçm:Ñùûh¼`Q­é0 j&#/Èç}n±œÖ5¡Õ¿ée-k7áD>ÿ (©•ù³"³,ˆð_°ÿÖþÑÏúürñû5ÑAé øþÜv8Îëêv°Qh§2i ›Ÿ³ö¦þOŸ­;l^55­=)–_’ß—ó±x´F iA‘ /1u?ÖØЈ´”>¯ô_€çøÇÌ>øSzGãö‹ :Ê ˆ)5Qø,jSèH|7¸¯§Ükšãrzá£~b1¦'ýéöHtp¡sHÄ} >‚ZôÅõÍk®ëЛ6(ÁËÍ¢ŽÊ#/”ÎΡ۹X®Ø4Ò¡%Ì4rôuôcѯu¯®¸÷ôÿ—ý.éVI†ž5ŽûÉŽJ£2’ÂÇ¥ßui'¬#7RÕLbŠåoÏ'²ä©U÷JúR™tÇOÏëßõ¤ÉÑ%„÷NP5$S cIƒÂRžOªàñyåÔîfÔz\÷—»h´ã­|‘Ñ5vLHZ²OÆvÑ=zÓÜÃQ“OaÌø`û§Ö_áÿç?½§ÆOå|ì !¦”‰KÈü†M£²>–Ȫ®Ò×Ò¬ˆ”–Ç¢eEv[˜Y0)ø#9IÁÓõïÒh¿ç¯ôòÝãþ"X#/Œ9Â&œÆ’'9æò<"MÅP…sÉ{Ç/_^®®SÏbtnc!Ÿ^À‚–½ä_æóã‡=1Ÿp^÷=‹o£Ô“3£F`›N¿„0 DT>¸Ìfæp᯻ÐÆ4«g?yjZ¿´ad.IY%egÂÊÀ;ŽkCⵘ)_ÖÌÎ-Êæn,…3ö@}ÿoÖП>ýN£ àКŒs¯´Óžõ>ÝŸw¼R…0ñáã@ÀI,aˆ.ïŠmBìáר#/à!ìBš‘Ý’<ïépD@5g7KXW˜hókïEŒÊs©å½|¾B箌G¢ÏŽÎéDun §ä²--£jjÒ<Á.ÜÉç3ûý´í¸~µIBG@þÇþÞG£¿³h‡ÂæŠöoáO5mŸç#Ô¸¾(žÂÐäö†©‹€LDNQ2ŠµÕ_ŠÔfŒ[ÜÔþì<8¸<þ£Dâ³, ÆâÝOûÚ­°OÍŽ¯nÛïpò €Ñƒ‚0! @Bwé>xûÇÙÑŒömÑÑÓð_ÏÉP"j @ÕΩ&vÀ5æ~C«4Ø;)Ÿ/§#7Û0ä±×Ý .Y0'ªÑ[1¾ CÓùYc"l·` #o/£²Ê—Ǩ™¿û#/·Ú_öïoçÄz¹]h¹>#Zœ¤Ï¥õ õsÏ=#/´|o«„¤Š·Æϱ†s›“¥ã×xô Ìçª^ØYÒskñý_JÆa þØ`zŒÊŠ˜ÙÀé„_!½Âmƒ*©d˜hBpe$g¡”Ë…;ÊÙSP½Ëi óï›>+Ã9ç¥X«‘ý¦Ï¹Î_讪æÓ^î·e2"­é“â6Àîî©{ä©-.jˆë–Ö½­äÛb{}>vR(Þ#~”EªØ=ŒSõ¿•^íöO¦êCU˜~PÁÊÂOênÍ #7I4³múUÖ`øåþ‹Ém·ž8«ˆ ³t8ç`yOø'néÐeÏøKèž“Ýúà®GÇÎø‡&ô;3( Ý~S¢>‡Æ9\3ç~[ïäôÕï¹±´ÖT…/ƒÀ땽×ׯqcÃ/¬5ƪQ?碫cËoÇ„f¿Þg°Q›Ù¦ÿƒz3ur¨—p\üv0i(ü#7 ‚’ÈÂD=ÇO7•¯(ƒŒUÜ^ükg-?îxL­ÒÊø)iÃá]nñBi8«ªýÛb7²:{{à›Þ¨*¢Á”Ý©EË·²¬å£Ješ2gºÉ\Xcq[„×èe€4Q|®6YtK¤$š`’c^©õ¹gùÑÇÇmú<Ôäû(ø;‘‡†¡ìG1JཛyrÑkévB¯]ãl¸ Æ%/¥f6?‰+…Ž¯MçØwzß:1gÉë“>k]s©r³–çÒ(³ÑɉÝñ_…f8¢á7|K‹8£·MqáY×kSÔ%Žð~ØÍ+ û)¿~ÞX€à§ˆñS¬Ü®«]ßZþ9cFƒt5ggL\®”j¶ˆ½‰5•ìϦÞz›”ª«»É»ë½½Zj¼3X¯½)¼TùxU‡¦|°zÕÎ}Ih[^Âó#/NÕ€L)ÝP亳«³Ûì1ÚWÕãuñÚäõwÙ“1KÅà]¬¿w—ðÛf§=5õEym:Gëç=Lp›!‘ñ÷ó^uGü0ªºÜ†™cO퇅`øë6†òל»Ÿ%ûÏjøïï—6vP#‡7—‘ÿCqOIÏùõ-2Šq6r$õŒC@àø2»‰ÁåWdÇ-“°F±ÂBjÎg·Å;O[Kâˆq×ïƒï‰øk›?mÝiýå7nò~2:Kø©¤Šá¸N80ïÝàNž.fÄ=;Ê^‹?TLtÖ]ˆ:ðΡÝm¾W¾¹ãoÆÙðÇZu‡#9¡Dt’w}%㢑Œ¿ÅÜyµ~6ðk\ÉÈFj«ÞóÍg¬z]yš+C-í?nçüy:nü¼k#9äÓ$qB–€J)mgÏ!/cÀ꺌$dªÄ–ŽJÃ’ÞÉ3+ß%‰™•]œˆäÃíû¦:”×h(r£'ñÖgÏlkS¾+4.H@¶Êlt‰Œ|Qh~ܺ"¦±X¶æ`G¯•s¼î½vC¬yW=—½ýJ í›ÛH ‡}ªÿËíøÇjäÙÚw§hG¹ãŠ¬&¦M#H™q&>¿ÅÀÀR’+ †Þ_jó«Á1!ÜáBXE÷ôîniTã;§CüTœ<‰S˳ÛÀé’üEÝ?ŧ.Ø9ÁÊ&M~QÌ>Yõ°V”VNm„ÌËÏ'WÐX³O °ã.7ã#9½’sœ•=ÂŽŽù=îÁÝýÕUú—Úð–ý<ˆ‹OÞÉ:;ÝÈá8:1MÈÑgȹš3IQ^å&ìQìM ™ãHó=8üvà‰‚1ˆ>—W´WY3}«GPWæxG&×^-op‡×½ÜÓã}n:÷ð·Ù³ØE*m£òf¥ËŒ]‚Nó…š²—ìîéàç:Ñ*iGå] øýpW~ºpÁMóLùR>y}røà^(Ë8ÑÉ¥Ö¶&d¼ZãêŠ#76YÔÄV‡#7Ü2eŒ ¢ü>“´Fdíd…¥¾£‰Oë?aùw÷y›g‘9~¹ó‘¢|oæ,úà|hk'òSKðyåÚ× ×ú {¸=SVINm‘ø6©¨á‘ÐÿŒÑ= @–ÂÇÖcÞü}^F.!¶œÖÓ“žN—ñ9P‹µ}ruãø_£ öý{òÄIIëñ®”h=¬%%"Ë°ýOVdN êÅ7l0¥}L§»zÑÀè|6¾m>±„Ñœ+ÿÈ×o8žE·¿Kã:Ôß2#7‡2Ó;>zÌrá¶;8¬m%ÈãðGÙÉÈí¤uý¼Çà†ã×Í;HÙÓç"™쿡éúúKý’ñŠ M˜ÐnˆiD;‚ Yü½bJ pÅCüæÉBt®7nå@óŠª#7›€ @¹ÊX‰*¹×qÂÄJìòú)þø/KyNi6¡\ó´r™Ð߃¹Ë³å2OãhÏ…û08yõÛ÷œÒ\ Ø\v i÷â}ôCšÚ¤Ë'7¨zù§«5 èš$E|éÆË«ú`Ù;´ësÚ†§¦·¾(¨¨…Üâ®tN°d4YØqßµ‘¦:OGÇØ¿‚§|Gm½éçõsI1¼fm*åUÒ@‘¡`1D]XŽd—òG&é8È{¬Mšaù´~‹êш’vmR“ŸŒ¼…(jˆÕCˆ8B®œÔˆžÆažl<¦ˆKIìBñ(¤À%ŠÅ!m&ß–_ëxk_~lz_?d>q×mkÞçàxn ƒÌ‹ ƒ4ïÙ„7aܤ}þ•šàÍšHU뤘Q/ü­ žñ€YvFÛCb&@#/Œ>-!\ÆÍfDÚQv ØŸ×#/"½37–O£ óHb‰ _è…|zj>”W®_Ü0¯å›V1#9{|Òµösù3°r¾!™H]p6Al—³»"¬WÂ},'f:¬tÍGEÁ™•pX‚×ÁG£¿m=ö1²2ry¹ŒOÚV- –üv8ÞM˜­v â;Ÿx×x£ŠáuÊaæ@ûFF( ¥dì~š.³ð¿ÊSÆ[òµáa†%£¡á‚Þ/óxþô@?¨"ë%3‚A €'Èù ÎH#9PgïÝ?ïù~‡üœ~Aá×õ#_Ù(²¤"€kWRCÖv¯ç真/ÀÐ#Ö#v´#/z})þ ³ÀW·ô[¤pýŽQ…¯ŽzÆî_êèaÔ>Ȧ¸¤‰þç>ÚŸst[”)‡³˜ÐÏÉ)N2>%tpû>Ý~´n)$ñ ¤mî ±×¤zø_ë»7áÓŽuóñN^¥ç:›ÍŠ›nCôãª*φü9?˜ái‹LÞcõÿ‹/È{ÇG#9#9&4s úÕºÄ (تAqOHåL@A$•ÿV& ˆŠ#/›¿ˆ=Äy¿G_âăO0=Ì•šd:8lœb ›@Vè=ûÊÁE(«ïûV—ßýM2ýºÑ»´'êã6\f&çx‡mZ#9+­Ý¿—ðÑÄL#7#xûDŸiв9q,”$§™…Øü¾7«?ç^ð8}œ‚Cñ––ì|—IO”‚Dd9ªŸ(BD©B€¢[&ÚΓÒyÍû{+“ËÜvü@ÿwÔÅ7Dw¿в¦Û}Y—Œ‡\žíPâìqÙ"ò¹É´:DáKƒTÖ«¦¼ÑAÐ?*ë#Ü(ùþVëng8‘–¢¥SšÀûîdõTmzÌTmEâ£5ß_VÞßËåE0ú„˜ ÆÑmr„‰)ÐDd&È2³V ƒäþ_#7*ñ8Ü5ÐzM|g·B)“Ý:u1‰AááðÙq#/jRž4~iéóì't·³Û‚öïÿf»°4À/J…(1ì,A‰Ù\/»žæo‚!¹‚·œú7fÞ?#¥{s“DæñaÛP1 4v¸À*Ɔš>Z)\oœ1“ÕDfk–¸ÞŽ}÷;9”CT»*r#/¶‰¸ž$×ãÎÅ‚¤ÛűêàùÅ„{“›‚fßØ ÊêµñÝå­× »—„:š* ­@,Ábý—Þ—)ü3MvóØ¢Š‹^÷»UÉd·Rkò!Y6ˆ©–#9#/´ªÎˉf=}ØiP&Ë äßç-ÔG×ßïæÊ#7²çàï­bøJ‡~[†É4ͲÊâkÅIä6|†S°áÂ3Žêá)~&âI–8š=ý§#¨0ŒyeáNZ•É,p†“îºf^ƒÑ*Y^ûc(XèxÑ…Mðã[ÓÃòÌ̆1Ü~Яl¢„©:sìŽvò×ç‹U›k·s¯ñ¸—³Mº>½Ü·Üx”àµ@rÖú]ÓÄØôÍShs´¢<_ãÍáÕPÑéM\ôœÓÚܶp{…¸îÜì‘A¯?‡š|5Õ+Èä¾lì~¨¾DNP ‡}VUfÞd‚Q¾zqÑÊè´i´ éU­Ë&ŒÐϽ‘J©ùs©_7þïˆZiT|® ]â=cÇîºEá|iÄ‚ŒÛ#Ó!„çÜ©7#/Œ•ÄPuï×(yš¾Mþ'”`Œ³žÛå«yÔþZš¹:iµ±e}ýmÝ·sú…)Å…·;l*t…/Ù’öºoXâ«çø¦ÁÊ1{z’^SuçöIû§!ü1ámÈç‡2vIÞϹt=S0…3¶Ü©w¤‹c@2¸(zÊw„‘U$ˆF:`óFRP£)/ ôzr¶Ñ £yQ}ŽÅÂãØÞj5°¹yv*Ñà©ü~Y¿/p1óèŠ]ßô,¹–‘¯OfGÊ3‹)Ò3Ì#7 ¥ Ÿ€ò*õÇ\IÂ×­J:2: çF¥m ßÝyíeL›}¯ä¶Z0çÝó¯¥Âå:y®sÄYÙhÜmÌ-ÇM0ÒV+31ãݧyƒH%Áe«=‡Rü‘ø*,¯”7! 7Výpߺ‚ëe`è†z"ˆ$EÎA®ÜëÔêl‹SPV#9'µ¥ìå¾ZÌAÙª-Åì3ÞÓÑ•óuajßFr®æÞsÞÖ—Uõ|²#9´âÉ׉y¸ÆÞKu«CšØÎœDiûç£OV FyÁsª†n·û áì‘”µ#9V#9«†ÌôÎèRÕ¬íºFïyÅ’´ì˜VÝóé~ý!yùõ’«Ñ'íkÄ0Újì²aPàç>{Ã_-¸¹£UÑlÓsòÝ…ó’ÉͳÍÎS q*,!ÍxÆ8—œâË-*Âö`Àæ ¢Ü“žaKè÷Òâ”)Ž70o¼ÚÊšqø4táäGܬ®¢£U+šo‰]|CŒgmš8åaµ´'O =nÜLÓ\þ½ú—`ìŽÝ‚”U„×oòÉÁáåî,õSùP‰Ì1æ|ȹlÍšìf|HÜå¿—ê¨bD?»ùÆj=×|“jUM@ò ­Cµ.#9#9¨óÉèä“+/jLº¨¶GÃÿY9ì¦~¯™&žR±T÷þ-"eš(bìÓ¨™¡£âö!ÚRtuÏåZ:CkNØipä©œs'„º]¹¿W(L‹zP­ÎÏ‚tšíÌ}òƦ|U^¬px8Ü2ŽÇõ€˜¹zÉ‘y;g‰¿ƒÝgi43Î’HæJLÒ#>ü”ÓÃû—:ûB)ÙӥͿ›¦IÁ{ôÎ3sí2§^W;e•ˆ(¼Õ¨)™¾E7OîùG$§²#/9Öâ€A°AÚñÜ3‘¦BÐÓmí_Uo­Õ8<‹¨æŽÛEb>Ó£§)@+ˆ|,òt˜ñoëR«ÎÇŸê@²3S§&ÁÁ&sHr ×É’µÄ#7cpzÀ¥+ê[ZE€”ãƒÁ)Ì53'žô¯®½éåóì¿d’ÆV~â¼åˆM²åÉ`7m)`[¦ŸƒÃÉ`ò#9-¢ÄKAé<Þ’:ŠcîÔÉè³Â?9!Ú’BL’I}¸èÖŸ=º¯)åëðÙ¶ñèh"V ðQ+´ƒ‘Trú\ÎZüuäƒéÍG'tzïBu~;EŸ;?‡ìiõÜ}ÞÑÕ;Á`ªkç3­Ÿ)uá&(¨ œ;^×#/ÛfyE¹2F{¦ež"ÀtÚ’÷„Ù!“솩Hn;xìw‹Ç<æ&„Ùd…³LWzøš6ÖíÆì´[º>Â40õç½MÌrñBé9k‰ <9Cøòhã«–ô‹ðjºƒÆì¿k†Ø$PV%èÓ#7«·sD‘4ŹvÕxYü5yï7C³ Ö<Ñ3àãž½±ç4¸=j…÷òñ‹ùø¹ù%sÏŽOÃ6^R3Õ-×jÇuàkú¸Ã?{i•ùéÜÒXŒ3ÄIÍffQ+%…3Q* ¤0~bc#/YFÈ(‘Qò-’¾‰<y7¥ÓÌnÔwj‚|#ŸçÖ«–XÓ=aÏ£—VÖqqL‡"…•#7®’1võ)‰ˆ…û{E7#7¡€yÙ£lÀæÙx”š÷È5ýØFN!çFÒF‘ƒÐZ›Ï;Ú’I?\-YÛÍ1|Ñ+e¦"ñp7Š-‚Ó6s¤NO‘¢zÁçßÖ¥kõxnÄv¯Ý†q%Ä#7MsËZ¸Jj¼ÄSã9%Ê–\.*„þ‘ãòs5á†þ¡¯UÓ“/ÚI'ƒm#9&>ûÅþ™lú§Äìiê5°—Ö‰c*×Ö¡~F÷Ò²„„2ÏAJsôu Ž¢¹ó[7m€¼Ç‡G±öMSx#jŠbÌ=a§TD‡$(vž *¶ ät=ZÅ„<-4#0EI^4Š#9Ù_=ñ ¬Évèˆ|ú»Ý †¾Yvá¨hívž‘mõÌì[†µfžËj'#]á«t#7…ÂL‚Ƕ³ùû!¬:Þ…¸ !Þn¸5¬ú(\‘ E˜tˆ2¯Ê/îøb<,X j GÍRñiV¢Ä#7]#/nƶcŒ)ª×% [pµEt¾Çóçfº~¼GlÌךcšpŽDÈÃîFÌÂý jÕN7èÀu4B7¼I9’E3pt–‘rp¡2M·¯$4mŠ§3r !¯ž™2y06hq·^Pí¥¢ä Š ±¹H•ÒévŸ6!çtZÃmËoPB CQ‘o±j׺Ém´Ù$SÙ†—µŠz(ça™ð}E¼·\oœ=t_Yy ¸ºëhD§ f‘,6³0¢ÃsØ>+‹i½Ì¢Û‡ÈƒqŽøuΨhCç|ħðfÊeµû±àu°Ðd£'go¯vLŠHbç ¾_ñ}† ¢a`!v#+à6RV¸#7¹ª'A@îu´X絞úá¤thá–Œ© V¥5¼€â5Õb=˜(çß6Ûý†ÙŒRŽ5§;F<¡Âí÷‚¦ûjî×z<™¥Ñµ¾=PµËøËüü1Ó4mŽŠ6{C¥ÏjO‚­òÀC¬ncY²ú¬ˆ»Š$óç­Od_6ÃHÃ,œ%¢-™XÞŽ¦èGH##7(-­âh@–ì m«Ÿõœü€ax ÞQ&5Çáj-ĵm cZÚ’ËBò#ª†Ú (&çX–Ž#9.GmÖ®á~HÂ&ºõësõ¬#9¸(¸U DèLµ”HN6Fa`ÑÚô”Áý`|~D^ßIg‰9‚ŠÜ¸#xÈC>ô’8CˆxR1ã°ô#96qãË|+°úsºü]Ÿ ¦#7Ë|á?b#¨L\HWÝöçë~UËå\ù`*d[Ù>º‘ŽŽªõ[ [¯Ú·.ÞC(eŸð¹#ª{ãÖ]k´ËzösRì¦EÊʸ¹€%5ÿoã³—ñ÷ûÅå×õ#7#/óï¸ cö” Gà°ÑÁžÑrhúNÏ ;#9ô+Èu\ù¥^'GGãTÁ‚EgI™„eŽ1œ¼c ¿$™ Ñ€!…O²j’#/vLß೶*5×-9Ì<2áÙ_¦;vv#ÛTðÁùÃxË­ŸÏPóT,ÕlÊiœx†ÇÏ"ÔÑ5/õXýß×ì&4‡÷óÒÕ׋]aà9#/ªëVo«åµàyœç°kN<#/|óïæàÜ›BÐ#7NÙ¦à5äyŒ§^_¯WîwO…ý<’пø§ßãC°óË!žPþÀ.Þ00?‰¸~´7µmt³Áž‚ÄOØ4"û0ÀêÁ舀ŠL#9Ô28~ÑpFv:|ÿËû¼,ÌÎ:þçéï”ýÿÍôïönݘ#9§¨ÌQïÌ02„œJW!üÑ{×ËíþôÓêõyã?ç¯/€¯Ëô™ÿƒü!üÉ@P`f¾±##8mÌÿdà’†ù_Þs22þ·ùËe4 !ñ¢¿L þ)ê/xOQ7‹±¸#/¹¡à °‘#/Ìÿm¢¸"lhN4IsþXÿ¬¿Ž¼'§OÚšff›Kÿ™éêÄ8É€ÿ¿HQþ€ÖjªÜ8xúQ»¼½‡r©Ì8¡Ôõ&ÀHN‡‰N\į_3jOg’#ƒMçŽà°ñÄ¡XßËÎŽÛt3ÏD¿™L7 €êGXL¶PÌÙæ<#7ÕSÒsžuHúÅìOH0w>>b~À„F¦>ïÓöû?±ù^{Oò~ÿï/ÕûÐQí;£‘ÇêWÂGPÿ—üþÝ#©û¶ÿsH‡Ô°œ‘~@øA»Ñú ä¹4¸&6ØØÓ³rcb†ÀÃ,îÑû<?íêSN@ÉÀãdvQ ì=»µØâžø—Èz úx" Ýü¿çgßìöß,Èu‡»cÀÖ‹À&xúAô¯:£ü[Ç>žpØ#7㬌wT§|ÿ·ŸÞž5ïÊ ‚š•=‹ØsnZ$Ž&ºÕ^¯dH<¿Ã@ˆåKˆB€JÄ3…„²¼¥ )Ú”UGÜ>í˜æŠmöýQ_‡âþ‚yu{˜62Ë•€ƒ•(£‡ÛÕ¼tø€xof™Ç´!ðÓëϪë~ÃðšÔŽIý_ðRkH\I:0Ž˜¿B#7ð±?öV!ÌJ1mMO¶}½Ôô.D|êÿpÒÁ#;w”uý¡×ÇüŒ¾~'^©Œ‰q©3xïÑìïà—\GwÈX#/þCsxè8¦SàŠr!Ë´ñÜ™5ÀZŠÅh@èhãéRÈi8-CåZTªãrÐø˜éøz˜§”'`yOHzày²3©áê˜õ„9É@i·îs‘8ò„ºf>r=…ó…3÷÷œs1¼ópÄK>×6ÇcP0ÌdÒR… kN°ó.@w¾Ã`^×ÁqL7ÒAôý&¸´A)ìfêKÖuàms§f» ´Â±É8`àâØ¡WÀ:Ãô@ô?d(’[!ò^h~Û&Uéü“·öã›%3úh_ËúBìR{ÿï}~ò|Ó,°ª¹Îë÷ÿ¤ñuãØ44M1„Ô0Íÿ»g¡j¥È0̇}ˆ?õ*5@3¢Ô#/ …¦Â H“­ÙzjbïÝöÝÃÎ5\Ä®âH%Ü„·‹™BÓà’OÓ nu8ýt:ë.²¢¡”¨ó(Èê>?ï;Z¼,V a°Ï‹}f.ɉ1ýŸÔì„ÌÉXÐm?oœ2zê$O†‡Óíºêj¾Ûûíz¢”Dï#/Q>Ųª0Ò|]ƒÞ7„ÀXRHEUì;×G¿Zí@ZÏØc°iÇKjt&<ù¹ç÷nù'AD󚜓/†CÒ‰ú&‡ˆrzêš$œ³ÞrŽµ,F#ìÚp; ¤£?Ëä#/‡)…µ"¿*Äìï›H #7»?Ȫ¤5ò¼ŸãsŸØx‡Æ~ÇÈM#ÏøÇË!,Æ"RB`Aê;ærzÁ9HnÃp=#9™Ÿõ9 Óg4#7Çþ•ÒD$ˬÊOD%ÖÚB—¨aÚÔüžìr–\tˆbÌoŒXÉ%‚ç9ÍRª¨é­VÃú¼8ɤ'wç§@ûŽ¡RÆvyN=róŸa¯YßQûƒŒð9™¸Å"!ÓPó ée£sÄò0Í”7-ÏëΙSnÄ4[x1yPàôˆ`ÈàîfŸ#/§¶—xÇ—ÁšÁš=z€o0úÇí /p¹D¾#7Àò»ÒˆÜ"ì½”~AüÈ'´À €¥>;ÿŸ.º§"xÂx#7㈊†%NO©QÖÿ#/à1ƒm_ßC˜›ÔºˆÛA¦ë­¦Ž7Óñ?Æ4+=ð›#9Ë_Ä…Edyk»Ò%žž ÊBà*pr Q™fÇú=_gÑñmºÔz#9ᥘ+°ÔìÒBZ#6ñ*Mð*ìï|uáœYßEøÎA7!€ á±*mþ¹JÒ¡_ÒGû6|Ž“8q±¡‰ŒM2æ²Ëœæ‡0.{{‡C» ÞAÐw@Ž áÖPm?‡@“ ÿ2#/ÃC¤Öt(ýžðÒÔ#7”yœA:~ð†/Ûõÿ¿â‡gâþÏ/Y 8Ò¾…:½‡Ôþ?ryº#9‘ƒ¡â‡§ÖFÐóx—#7Øk^( ²ÅñÐ{ÄÒk:u•¤#/7Cþ¹ì52dSˆt¿D?Á‘¶a>¹CðÖK¡¿D´£Ü1i;MȧœeŠ/"âC¼¥:nT£Y Æw#/êj`7„—0¢¾Ñ}~…}Á©¬c»ï'ºaPMD)]n»‚¯¨5›œ¯”$ì öéG§…ª*o#9ÄÑ‹ØÃyUb )˜¶L2 XL”!°ŸÎ~Àý<_¡ù‰¸ñþðömYØ_êaWìhD _Êâžæâ?ŸEðÄ‘ÿå”ס·é8q®ž½uI½)2õÊ$Æ96#7é©ë륛¿é~ Fçvu¹†q¸Ü"ÆS4Jë#k4k4õ­Z4Ì´l¦àiõf©4øËQ”â¦îFË•×)M•&íuêI$“7Q¦±IŠ™u©©-ǘÛi»šÌÕ–½f=2³ëÆ]CzÂÕ3XŒ±#7 7„1š¥ÞóY£\fÑLYF5ÈͶÙþH2nÿGÞ¦3BQD+’ã Mÿ‘Š ÖôÀÊ)±&Oä‚=Ì í@Š•Ù’Ll½\Ú‡_›¥ºÇm‘ ãñ§ÑjõæΠGö$D”L"!„þ—°3n©žsYUù°ØÂ(¦›Z3LAðOQ€ê#9=žïâúÓô#õ~"yªvv‘°´ýÂwû-Јtí©d»ÖœÐŠ) ŸcÈ—íßÙÒ´—X>îÔÐÌÚÃÞ˜ŽÄBÓPÚAiNú‹dN…Pî]ê‹5ƒ‘B–Ê)6œ2NŸùmƱœšLñÒôµUœ WÀ«lF‚˜ ‚ Úåwn‰•ðÌËÄ¢{¾IãÔäÖš ¤¯.†T¡vS€ÞP Æ£˜¢P'Öís›²zÍJÉópŸ êÒC‘€k?ÒeË:Ü¿dóv⛯«´{˜¤¥š†$`}›òÕӌݩMÊ"Š\Ù ÁC9‚ºûüϧ£êººÉ‹˜ÂQJ§í=À{ÚÉ>bˆSEu¦ô¶Pj?»#© Ÿ0(˜ 4ð‚(7 €c÷xù¿Xcih3|-p·@ô?Œ€M°i€4µ0PÃúHW}?Ÿ¯†à=ÿŽ/Gˆ@^ðÙ¯Ò '+èvòT/ó´G•oâ9Û zvaˆ$ ¤u|¯c¬¥öçèÖWèßh ú×ÌúÐOÃTM»ÄO“G˜ÜùøŸýá>ú¿Kýÿåü˜w=?#9ûï=#/y~`<`ÐXGÛÉ:îÒ„¡!(CûOHGèp4|^/õøŽàýèx÷G¢%™Ç€ï_ò¿˜ôŸG\ÇŒ‡V?ÇÂÐõëíOØwx‡´} >¢TÀ’sd{€ì}Þ T¸\ƒñ‡¿A)#9À}zxù?·Áº ìܳ”#7Ïìg¿#/‡Ða7P<}·³ÀÇU—ù;<ãftÕæñ=±‰ê)iZˆHˆh‚>£Ô'/”4õWù ØÚ€Ÿ9Á1TëñsØö§™÷þ®Gk¹ÝÞîÚ øÀò„õè~5§kšªlk£(Ÿ9²Ãúk™ñ×îýé'Ïö§ÙĬo}1 n§D>µ6P4ÈQôï5U}ˆ îæ_€ Ã÷ôJM‚\Š‚€ öý?ÖIüàÈ/îò &|χǠg‘ËÄb%¿Œðýì>bƒ{TÏ'HÔ[†¶¶2Ô÷øqx̃f÷1³óò#ç@„éýŸwŠa-šInéKY&a¸w~¶çHzõ ƒ8˳í*¿µoO°òf«ñÄpað^ðòÒ§ÔyÀôñƒY;"HÃî#9±“ĺ&¾åÌã}ŸØvÍŒx4FEÒ·ªx•°c&qã®ü#7J²!{+Q¥GÊJ8™6",øÁ,jªiDãד„K‰825–6Ævåòq‰•î÷}ªnÀlõDL¤-Q¦Ž¼^¼ù»m ´f9¼HÉ—´î„–tˆàõO»ÃœùuùClÔd5´#/$úfî¹ÌX,‘@>ÿ#/¢ l•±VÌ|û'±<C¤²Ä±¢#/Гôí;ÌDùÄj¸P]Š6U+¸wœ§^ ‡ÙáñšŸ)#/öÝi°~ZÏÄ<„a4<<û;_ä0Û#/8Î<‰çQ=ºšd€R!Q•J‡8oDï=ž4óäŸRvzî„|}ž&×ý¼ùþ ·N¡–D™•@_Ü’Ùï\üáþ‡þàÂ4DÐäŸà•yT”+ÿq 8:»ƒ2çF”A04ÁE¼V⎰4ã‹’7–¨`49œ‰ÐtÜÏ^è#7®LD¯_¯™éÝc y¢Wj^#/AÀ!†@íÆÿ.8ó]|gû²~a'âIê*Ž_aþ1ƒôÊÐ5¢Ú ÞAñߤ#7Ÿš„}#7úØ?F^„7½6@žpûa¬3¢rO„%dŸc_‘ò gØ×ÑC*×ÜÁÒ1ý³[ÂÃT»—.F,7¨·­ÊĸòF’¦s+P#/m$˜ÄÙ¶ŠðB!î×PAH?ËlÁ€œÉ€hä*<å°Ã“.ÉPÖƒf$ÛJ” î‘w„¦T€bQMäÃ1GŠôN/ÐÉÁðIÀÞWÇûUWº©}¹×oCM§@ý¿—ÖmùÂQ#7†Y¡ëúóGÔûu3©Z*¦°°'tX*€€G`ˆ=[”õm؇^©çà“ÞÓšœNƒú:-&'œ†õ£¢" ÷~[“ñÿò;Ut U_â}ûËrKóŸHW"ÆÛ0+íÚ!í­¿lBŒ5ƒøÓ+^ê{õÆ¡³ £dÍ2Q_'y[è(Ûš¯JæéÛt†Ê„Ä•š®Û¯<Ñ‚–Œu&R4ÐlýÇzkŸˆ|¿ÏúyÛ~`5‡Bv¤n}Ÿê>öOŸC#9#9’{±&ß|w8õ­±>ÂSOùþ7ÅÄèõB~øj€<Í|ÎsöNó1(‰0Þ#/'¸M<3A24Pš#/ 6\Á“'m)p2nœ¶¡$6凙M œD÷©µ|vêÏw™ëݦ^QZ>>‘ßµêãœ^ñÝ!·îEÒ¸¾aæJ€dá¼ÌÐyx°ý¯ÕEAì­Ù#ÓÌ53ßDî`ÄëèQâ!Ü8ò(åæÀ®dí• ²*‘R²¬öü¾óžÆ?côlŸž™TOalå\¾aã>†³>”Ò{„Çb*¢¡õB­-<ÆôɆjBÞ6Fµ‹æ4|Å´•d’Gêô0}ØÝ¡™Ã¿fµ!@‚š°#7LH4•-Û!§)$Öxú£Î'æ òxÑݤ¹C5ÓI¤ kãþrw±B!ñ:õRq²#½9î >0Oqôêú>¿€ùZ¦íOgD|Áé=ˆpFGG£Ï&,þöz¢'ª_®>àßâ̯«´ÃÇÇÑp}9ÇÖóz?Éùí”0_pi Œí«À3€váè`–¥™ ¡ÑàÏZ@A- Jª JšX¦E¤459ŸqŒ¿®X/×?è(XçØòŸåèOÕkÀzíÊÎöxéühë®$‘¯Ô%øëHæ`ÏïG·]ëÁ€(“Ð>sˆ¾ü•{Ùªu†‚Dsã¯Ã&(C¶?aù`©=Ì}i¡08ã üJUZ*æ1œ(2ý8S•Ë庠ȿ`¿r}iÚ Ÿ•€ÅŒÄÀr{#9L—”áaŒâN¡ ‚K˜´¤!JCü#9ÿ.ïå ‡èwååö_˜3Ùë}Þ\µæüÊEÈ]UqÅ…¢ 2 `NarÏY©Í£;Îò°ö#7€þ¸,úý2ŸØ™‡w?Qˬ'`8#/{9x+ëÞx‡RЫêý:M…%TÜ8òQô½“7<ƒƒóv|}Ò§ =î%ìaãáé,ô¸É$Q¹¨ý:Y"aÀA»lÝØ›ÊN2É$uÜÜI—Œ'ˆc¤ºˆ¢¬:™ŒeüÝc±è³‘Ò ÖssüÈ£—gŠ.4TJ…JÜ>/Hë|O¤sŠ³¥t{PmÚUBP„ ÃOy*¥›æÖÒˆxo€;·¶pbž0ÌX>Z,’/aŸyâ¿«i~,Gž‰ÉÖû v=ÓωäoŒœˆ ßgóŸÇß}äûDGÎ!/ÅvA»Zõõ’'üOa>D÷Ñ’‚' øBÉÓæ5¡\þ(Öè,Råí‚û117:óUó§êüžƒïÙýK¼üÛøþ¯õÿ×P4.éÔ?oå3Ƹüÿã6Ÿn”Ù?À?")TWÞì}µa¾ìÏøS °<ŦaØ°ÉþE]ÅdLøDùç÷1×Ö<ý¬ø+ók÷…OÙR¡òû¨¼åµ‚Á1­ûѱDþ÷?#ð”çä~ºg5[Ä™Áçÿþü;:Êã{8Ö3€ä8}‡ê®Ùßþ„ïñû#{Ó^;í.ó?^Ýèíë–Øò€†5€IPÙd"#9ˆ˜á°ŽfôH#9Ð9`'g× ˜ ÒdU%@ü²°7g½Üä C@OˆzS¼Ðþ©ùý‡6Ø^Ñó¶áú?R¨,þ¨Z8øzL#9 Ì ‚¬a2Lƒ ïz@_`z€Ù|ÁÚ¾)äøô#7®ÌÓ@Ø=qR³Ðƒ#/–=ljÙ7ïßYALçöÿw>@ŒÉ>{“Ið^˜x ßkßaxK£ÄÏbÓ¹uUN ú9 ö£é3ßØg0õ¡ëàlÕ—eS³‚GŠàÐÖ´¨vX,ódì"‚[4í ˆV#/ˆPhxrö–©×ÝâPûÙ®Ÿ6–€ ÖÐQðHÌ"±@mÖŠÔPI±õ=1 Ÿ¹­µÄâ(Ä}yy+ R9ÅèÄ&¶> çd6ÛSS6ÕVClb¤¦+·ñ§Ì:L°ý‘HoöEF›åk-gTÎæûûÿ0ƒ·î?²~_óý&úŸ9=Ç€Ò`T$¨aêõtA4z„ ƨ£b€ß«®}nä@–îë/MÝç^E¿#7mé8â¢bäN^~ßOÅyY‚x9BwËÊ¡8#/áȃ!À#7„Cô¦’ÿ÷YÒ¸ýAϼê ~¶#ÆOÓӟݘNÃÚvÃP—Ïó%̇ö¾töu2(®Æ J3ÑíÛ¼z!ꞃ}€Rðš#Ñ‘WÓév‘ýF#/ê:{<âôˆû>Wßi$‰ ±}7k®’&ÓÕ€¯íŸÇ£c m€týæÕ)9ÒYáZz|kúa©„#7t9i„YþŠá6ø¸HÐÐkX隌3Û1"f aÒ Ш]í=ç/ö÷ÑÜ{À=ž¿ŒcŠÊ1#ìþö–ÁÒHB0Ðò3„üƒR~G»QdþÇ£>çí9PÕG•2jÜ)¯}ls”äI¹.‡0ûN^ç¶téæ¿•#/Æ$ûJ„J#"‡{}€©´|¢ØrüÀy¸‡%…4”ŸaòËÝ#ý2‡í-°Ïœüÿ,ú³G«6ÌxŠn|_ã÷õ^-þè¦?[ñ¢ì|Çk÷Ì`\pW~™Œ਱€D¢ˆª Ç—ŒTßúœF’™øÎWý¹öDv’CIÊ~ ø†R÷öЭ4>~2pÀ¢„KñÒUãQ¥#9›" aõ:4½ÞÓZH¡*$€Cn@Å{F¨m²ìX4ÿ®7ÿZ<€MòMØXÉÏóî½™ ¡õCùßó¼kåý0來H‰­yov÷jù#/#7K` ¨Ä˜>GØv¤œÂÑ‚FÂI×–9 áZ‡éýð\>ªè@Aˆðõ rSŽ=¿¹¹G÷õô—/¬}Êà6økŸÓ/ÌŽ¿†Åkøþû#9åýsK†ØÀ¡0e2BgYa„Ì,Z,ÍJâÔRèÔ6k`Œ“…F¥>â^#9ƒ™¦ëòyI˜àÓÿYH®•#7*#9+èA˜:CJTÌSjÅM?î µ?³ægaš…ùÌÏ#/›*D`[1׈0µç÷B3 hõª /âÈ.&ùI/kÕ‚Ú³ž0\&¾'Jµ¥Ç0oƒ“y†¢#7d)$tìš -iXZ¨IXšÀòÀÒ,b#7úð84b1Æ´ˆükø&û;Ççû~«u¸®E8€‘=™_7ŸÜ·«þ”ýº€˜ú͇#Ôª1UeE@H+ÎáöËÒ¬LG2IÐç×9T¬íiþ¦g6Ëc‚l7È|¶|‚ãQL$a+ðƒƒŠ)úÏâ¨,)uÙ‹´;IO²wÏ7-Ô~Ñ&óÜÖ´ÛRsþd‚TZá#/¡^¬À9wò#9èx0µzVh«¸8$'¨¶¿7³#/«tnÔ·®U>‹pÓvG˜ªˆD#ös[íLOë×s¯×^d£ƒÉȾ;¿Ë¿ó¤met7h·kI4ÓˆÄx Ghdw«¾ t/z7ˆv²yÔ0#/y#7#7†ˆa…!m°„Š¿Aøgˆs„á…&‰(üý?.pßubÖg»íÝÕ­öÄÇç™cïùÞÆháû(¸±¿tûŸ]P¡¼÷ÿ!DÎ_cÛª5Õïa#/òšéöØ4 Õ*,üQ›^^;ʺ™$åFÇžj¶rQþMÜœßÓu.Z6é˜gÕvZ -3]Dv9Q@FøsÒÀAÎΫêˆ7¹óñ?Ѓ:OIó ü]·§£ãkÔ?Üà.;á"Ç£â,œA¥Æ5EK…;%¹ÑùWå£Zïå4«å”THNà¢NúJr?ÍàÁ¹…°W6W°^!#/meù_Da¦éë=¾i’ë„vK#7¢/…%®9´µÿ‰z©T|®öGäup¥5Úë4I6–¶ˆ#/µQ Ù(¬vF­4€é†R_{Æ×X÷2Ýh@vª^`ª}fÈrÔ©œßouÐp´Î¯«„J âÒ‘x»*hšÆàéD™…#9QAE`ÓÁwÒw pÖÒBs}²dºæ1)Rˆò‚é*$ʪ’ÉM–ÛLñG ‹t<» ¶ †”{ö}/\\c¤S!KMn‹¤ËA#7¥¼Ïߎv‰D½n7œJa Ø]Gh ëN.îvåÁ#½iC{ˆð"¯ÂÊóÏn:ó›Mâà>Dîæ`uÊg]]ηX?Œéûô¼ÇHÂe¶fجL›ÒÏcŽmhpªž´9-”0Abh©š4¾=]6ÍH“k<“Ž½7ÛUì­ÓlIL*ŽîÎVL ð ¶*Q¶aA†NwêT ¡l!‡#7W™×i00´ê÷ÿŽh€(Gˆèý^O„|Åߦ^œsâ‹ÜŽ"Álv÷£bôJSá-{T‡õÁÓ‚¼I·*»¬ºÜÄ>I>*‡Æ@Â$Zûï”\²wlž^Pv»#9´¨”XªÄŠ=]Oß­”•õzf2ý´>}o¯7ŸÙw9×O¨Tg¬Ù&W²ôAI½ê„ýлavƒ+sÐás‚€&”‹Aê¯8Â$$ß’bÑ…Ýn™›ßèæÊñþžyÑõ_^>Û?É^,ê<øÙ §c#9gæ“‹ Ñ;_ø(m–Û˜ás€Òovp€GóqИsÏàçÖ”?&ÇòÜ#/ìÿ.…çO¨ø'Wl+wz£¿w öE7nÀSÙщÄ.þ7úy¯¼1Þa ¶ÜòÞº@„Bõ@¤"QOö¼·¹ÐÆ{¾L~¼7xé´šž“@s§¡…Û¦1²S’}¼Ê<Óãšµ‡$)R¼×úµ!£#7|µÂ Öq½’#/„@¤& pÃ…;ã‰RfߣÉÿ/¦#Úûǧ­sƒ°Ù~zì§øMË{ýn:%uÁF?¥x–~º:Š$P&ÎññôÍï°Æm ¯n*d̆A¹6CU{Ù?‹iîv`­w‡iY<½uïvà§Ð"Ó3!.áé»I#7Õ35Ç3ã·§®Ž§g핈”WÛöÁÓŽ†Ñ,g.ÞH‹v¦Š†‘1³oP1Ö‹)JJEÖ@Ì*ÄÔÀSðžÍºòŠÄj¡°’¡9áÌ= )!¿ª#¸Ð‘’©µ¹X]VHòóˆÄ¯WDÅ\~¹Ì`ìZÒf˜Ž›‹ëƒ°rÆÞs ù™%E.¿¿Üý™Ð–fƒ¸²‹zp€ $ ò!Oº|¿ÞQ—€«ÙÇOåûÖ˜‹@ ¡(åÿ'z Ý÷­èàà œQEB=Å#/ ¡ß³›@¾r³ùÁÈØéщùa_Ôjkó'3Ørý?g×ãö½xËB#9¡P#9'0`¾û)ôó¼~XLïü¿Js„p@?€åA@$ÈûPØ·þ]l¿l’Q®}Ɇ$hÒ?ÔàLì—}ÓfÜáÙÁÐvž‚ÀmÜÿ`6ÜnÇ lörä 6v;Nã ǬD™BFÊñ‡úîNç³ÊlxÕsƒN!'†w/õI;®ª"%ƽq¡(r>a!b+Q™a\U纞‰S²_%Üâ#7ˆ^¿¸W$û~ú{´¬šlIH# u tä—k~±&òžäåBz¡R¨>Íþ¯>;t~²Byøsµ“±rü½ýwº[“÷Â0õðÕ¨qúcú]ßí¨³?.ϯÚ^“Bz<Ö– ý$zá}{9+Ò ÌVœ4¢ÖH65h.­1¶Lµ%D#7#7¦ <…“1aq–} _ðáøƒ™ƒTD .D¢õ_øÿÉö«ÚlÖRÆ™HËbÅú-ðºÃñž«³¼èi¼èÝu*f‘‡íÿ ÚŸXøšWçCÆ'á1YwmÙ¿Ì xž'üqôDUUUX¾ŸEL„!C»8`ÉÒö÷µ€I¹3:wöšÛþ‡ý?.Áìì6^ETV"#Êù»ÇúÍ{{ŒXg·*’bÒT›nOØ'“gSç“êF„-°3b+#7BG?p@!Pgµ{ª¶Õ±&´ ‰{hÊzG?öΞÇ8su@°ïM¤Jàr‘˜Ò Ò*y¶ýFÁC©È Ú¨ü!#/½•œw#9-€Ñ!àƒ!Èœ¶@ÒíÈÐvÖððìdïŒèM<"¥´e ´—E¢#sûŠ˜6û† š¼ccFC‡?ï¶ïpùy¬ŒPknœ¼'XŽ£)¦2ᶷ®3NÉ“ž5’Ne¬JÒyɘ¶ >)¯ê¯ÕÕ#‚ïaï5Zl&DØëþœÂˆoóÈa»FMÃfº"fÑï%_KÄìcBr9‘Ðwy*“ü9Ž}7ÑÌM|9ÎÂãQò sÀÒ5ÿn`H5‘êšú¼}8÷ü¼ü¾{ßj(ˆ“!!"«åD´°Þüðzä×Ü­ee™hƒ6ªU;¢iÔˆ™2ñ6Àz/«<€z66ñE0pyŠ÷ܤL:ˆ\ g9­;Í–I#7ÌΈœÃ¬! çpM/_ è¢Ü?¿©ç™D”NכǜO1ÛÐç#9Mw…ðÑ ³,':ãÊÒ§(ôÆ8AêlK›j£âM#9¬Þ‡@+û¶*iôý7°o‘ô|A¢»i;NÓ£å %_aØ4s;¤™4JÅ{oŒa !–¿E‚ˆ 6êVŒ4 õIYàÞAÆ=)ÓÄ-œšOLýMëÙömËÙ‡#ÛÝîuÈw0;þ¥ƒÅŠ׳î4:ŒÀöÁb£¹×v#Ãv0Hrˆvß$tž3#±;×U¹´êPVoÂs#7ÎÞÝà1ÚÓϬ‡G–Aˆƒ9qÿ«”Hô¤$ÐC”ètM¤(zuÔy”zLGa!ˆŠì7äÖÍ ðF(kÅzפÐxl<ŠRΔÉí+Ðá5œNL`xüÌ”W>P „hÑß߸ŸŠHHÓ°³§pC€Ô³‘“€+ÆvVšyµ‹œRI $E˜¨COLê^·ÎЪ0#9³WKoTÝ¥ÞéÈРƓ\­|¾C$[¾È; ±z²‡#ΆB¬ITÁë‹cšìdzÔ9Æu˜ÔÊd˜í¦†tÆÚK³/Å9,^Ƙ‚ìÔ‹$£ÊcËc°ì7L{nˆÓ™ÁŒ”ÐZD’N_+]àYÂN’è9ìW]ØÞÒÁÉÛˆxúóS0c-Š¼Ì¸ó3&\ÌÌËf5•fY™$«³kÊGê˃ƒ“¦w’½B÷~:Q°lcRt<;R Œƒ£LNYáÄÖ·*j)Û´ÍÞ%–zœ}œÝC`ÄÜ™žµ@£!Žª‰‘0„53„l³v2åèv쳇¯''#KIÒÐÝÙxN9òÒPfñ=ƒ©?o™.ó ‰¦Á¶Àe„M,‘°²L’ÄÂd· 놕ß׈´Œ»‚Ý25g½û+Ú†µL ÍÄ,Y©Ù%¹/§4ŒkcÞMïN½$}:Xì6úÏc=* ØŠ­‘2Áuuàôõ†²iÉ!Üf#”ÑJ#9 µ·#/ñˆßúÐSíyxÅEVŽÓ=DuâˆôÇnS#/ÿ =­ÏÓÔëgíx,#733xd„œ=í¸ÔŽÇœ×g™Í.Bîã sôÒ6 `v¾}>Ê Z[>ëãÓøZñOfDgEAz1çp¾Ã«¼¡ÜâRu¯’u÷ 'ÉÒdVâFètË;sø ×D´[!¹“‘›Ú­·\&»œq½Ø1×¢âÒ¬*: Y;÷>iÙðx¹Õ;³¬²œÜhíÚÇ6Ç–\¹X°øq¦6q} –^aRyÀ´&§QD^§(Mp&LÌÚlÍdG¯ÓÉ9|Q\¢+F“@x% ‘!p¡®ys4„æ °f1ØìdÄ£#9ªvþ¿Ï‡úÛˆ‡ÀM7P,œa¹#/òÀä…C¼TÖX“Maz¿#&‡EReîÏd³ÀìÔۚȖ]ƒÉb°¢MÏ@ÁÐî2úW¢ë‰›åäÎòPj…†ž¥¼$åꥢ©¥h†ÖÖüÙÙÀ‡`ƒd‚#Ôòkf‹¤EáСˆ¼SЛa1Ù\Z¢0ïǨÊ3u3ŒvžÕCs•Êó6²Õvç«&ä,Ħié˲±ÌLò$ãG‰ð÷Ù:ƒón‚I¾&ðÒþlJ u70Øn3]BÊ#9Dj”ÒÊB’Y#9,`Ü¡({àtêT¡‚)Žu6ÛM&ÒC`r`qœ8ÃY­“pÔPàâY™rÃh°ãÄÒKo&ıa#§y#9i™„óUTlÙbÖRÇeá- ¥Štì$nÜïaóUìÁ:YC£8z§ j¢#\qIÝñªõŽh}Çf;v`dækÇsc™˜ †!¥(’Yf‚'ˆò9!³àiñgäʆ¡2H€‰Á,áR,#9©Ø3lB§— •Òô9‹) C„ñ;d'”ó5£Ï܆‡¤µ8Éåç‹¥w¯Pw„ô¾»ÞôCÌ`«ÄØÉx&s°é8C}Ùa½` BùCb =ÑE*³ØLl©~pô×Åë½*ÙÛ:õæ‹Mì`Þ#9Á :Ê_‡ÉêÞ…Îo4†±µÎÞPÐÚ’¸ú´ž•Ýz߯žoœ¸Ó0FA‚A#9¤6Æ@Á ì Æ{ú†Á-ÔǺ( È 7K*É&Ò”#/ƒ–äJ‚yËf°,(ý½¬ãäjcú<#9k¬ †@(§ÑÜ}‡¨©—É $¶’a’“Þ›Y¶q#7ñD5 ã×ô>ó)™&0ŒÎ§ò†‘ãϾ(φ ú»EÕîxî™ïsEª?¨s"¥õzoƒ3Dþ§ô HþÄDA`p¹†,ˆ'|m‚ZýCþDÞ¬|™P†Ó§wÒø5iú‘¦wõú¸ôAó‹Šâb¯wQwý厛ß.ï‹À8{¶vœ 6^ËbÑ0¢´‡¨Á}‰ïT ÃÔtÿbð"e˜abe⃀ ±R ©åï÷½y'§ƒ‚±ÑÈŽþ`ç§øìÿ*ô{¦Y‡úÿÙ8u-Ed·søÒ€L$}%LUD£z“åTKçï¼Ôö—R”[3d”gZ¿•°=žÏ‡¼}Ãé,#´ø1ïõiýD¿Aè1åÄ·ô?›Ð‡Ü‘DÈ¤É BŒÄ­íÝD›ñÝS2”k¤©âvsÔ€ûzõè/ È:LgOqñªºL†¤ZÞ^Ø 2AA‚ˆû÷«ETV{ÓîåàŠé$><çt¨ÜvÍö6ôyû{ÑSÊ@Ùð*(¬\ùÕߎؘ|zþÑúQÿ@lÈ™(Œ9(.(/»®#9q|Ï™%÷xm#/ïã´ž‡ß¹œ?àQ᪢yô;‡Ê<¥ÉîhÌN!ðWÀý%ö6#7`O[hÙÓj3 Sâ7ÅÔ¯!JŠ| ûºš"€Ž8aí„0$t}ÏšÇð–eM"7!:©!à©æI¸¼>ŒC¨‡aŒ ‘d)Ó´"w²\ñÏÍöZL˜ieÝ«†ü›9’dn i³/6”ÊfÌF¹hȉ«ØãÁNF&ÐR´SšØ§~bðÌ g0剆#hk@ÿ#9¨BXƒŸwÈy³æsfäfŸK'ìÒjqH‰Ëª‹åݸóCÔ9îÈ*ÒÐ_Ô™#9XPežÿ˜*#94œlF>#БÖ+‹eùÉÜæ½Ð ­=#/:³zíÂä¾ ×ý¦B¹OžÕë:%`çF‡«c·Ä ŽûáÝÈ<=7hÿ2I>#/’g>íÉq“P÷Ê,+ P”:îëß긾€U_I¬m\´U-2Í¥IJ?ÎGÌO#/#/÷KJ'óÀ`C„BÌ#9q2€Z²«Ý`­*Úîíj¹]…GD%E•|LíáèÔ}Ènˆ|¾ÓɨþÚgLEU&°€áŸ<Õ!ö4J88ãpƒiI•¨•¶¹x¦VÖe®m8N“};ìD±„°C³Ðv*¡ÌØ6¡Â¡ÿEuI0z›ñ潑¦½Š”’bÞ®»xõM·7©½Ms]‰Fîí——]F¹nþžmâæé‹sˆî·7M’²•ÓIÉ{[§ÉäòÝ'¨a¶¥\ J ‘“úñ#7ýH.V‹?ù¤Ù6An¶ßj¾·Ïi|ÜDù®l¿Ábº#/óÇ#ceîô¬z„UH¬{CÅó„÷á~Ÿdÿ¹“»ñ+“TS$ÍìÎèÄè‡rë_œäV(<Xn¸óÓµ¦,e°¹"G¼·ÌðÍÂù¿Bk¦RÀ ®#ÃIvœ'Î3ѤtÂËCJ\—!DÆ#9 ”M¼±eªiöãÔ‰¡¿oE®?ÜíÔ!#/ɘAå ŽH9#94—‚6ÍLÍH\¿.¿êñ+zÖÃR+j,ÁŒ]G.Ó;žFæ8±‰°è#7ºðþáà3~æ…Ü^>aˆ_/=ÙEí‡ï5…Øx6UÖ^€}|ÆÜ.z½·D´ yyJ±êàÃðþ‚cÖq‚vI'ÛWV£®2a ¸ë O8ùõµFçwª]“ó`'ä„#/b#9bIìgIê۷ט¦€}]yïƒXzÞKJäÕ·x?"7îÃŶǴ¼gBspÞ/%Ç8-¥Y ŒAŸÓ3öîb™ íüƒÍ’f]¶tô¶“è~ü>;„E™fXF'¯Õ÷§£Á<ǽà J/Tù°þ:iy¾Ï(ü¯³àõ}° 8èöQ#ÐÓv H ’+ó#/íèÓY÷˜ž¦YŠ¥P:…§gr´$ñ¢L`ÅUAÆ\£ð“h8AêLåûtkX™PÐ]|ùWæÊ¡i¼B˜Ì‘µÙqU#74„¼½¾[òÎÀõòü¿i^¹ŒÉ–&1ŒšþIÔŠ÷$ݾ˜£ä1qb \¸âý”ˆÓX¨¶Ñ¶Ù6Ôm“ÍXÒM”IQ’±Y´«XšU%¤š¢ÑZd#ÀPA3#/$ªÒ3´©óé]÷áxkóÿ¿š¯×h‰ñ‰á#9Ð#/‹@4#/˜¶@Ò̦Hhe¢ Àz ÙÇ|„×¼å¥;–¾—É‹š+w`EÂýVæ@¡€ðÐØ늣¥D†,֦跤´#æ#/_ÈB= #/["›û¡à¬<™g5„øRyJTÏÎb $V&zq£l ê‰ppLx)·JæÆksE·½Ávž#/naG0!à.Ô:ïvêC°Ãi$îñ}:I€°$úMµ%kheªÛ ªÙb#/ôîTÅ@Ô#/v#/˜øq@î{yä³ÉêB ƶ#7&ëˆ±åŒ 20Ù#DŸÙ¶.ñDµ™!!aÞDú¶SÊ_£ä<$yÙL &YvˆôíïÆ#/È‚‚8öŠh¿~‰Ý5dÚ"Ù¦¤ÚiWÑÍ\¶(’ÔV®mÍnj¹LÔ)P”[3¨©-± ª¥¬±Š#9§íÝûßE›7 ÙÖçÅëß…#9°Q @ƒÄö3 Ã#7ÞvÜêßo¿®g¯à}*8;9ÑBE•3€aÏñMJ!óè¤@êûÏY¯ÖÏvR„db¾ðû˜œCͯ›*>“õû?áü?G÷‡äÿwû:Ÿ4¨žø*Yù/ü"@~VB€,ïõYãT^(¡Š¬Ý˜K˜¢dî°•uP>îX##7÷½#/ à €†áUL4>ã˜qÐô<<;¬ÒMØnÒcƒãÍÀÙCyC²ÿzE] 7ƒøÏã·ëÙZ3úê£A¹›êÌ`gêSÁ‹ñóÍ»ÏJ‹ I?Ro~e%ã7—«Š»£”‰Û|CÔF þ©=è½±žÞó¼¼sñÌþ\{˜9°dPÈG—òýghÁ"$óîÔ÷vŸžèyJó¦Á rÂ.*‰šp6‡ú²ù‰«ñÚ TbôAD½ËpUx4“ÎŒ©m9‡Fyñ°t]ƒd@¡ü°¦Œ8'blèàŸ¯ÃÕý1éOaø{OWˇ½!{{ÌžÔ¸#/hH$óPkÞošßº~íh4Oó&ˆC[eoð›Ï.g¨†ÁøuŸ$/'¼=põ‡Á/ñ-õZ=ßçuàÅEü:^‡¸˜AÇðyz®3ÍÑ÷~.™‚]ê;Âé#"Oȶ¡Èü_«PóÑD¡¢=û¿¹ù׆œH3Üóàwï O³ÀÅÓáþÏPht"kõ’Cþ„$œüý!#/v/%=IGsѯ}¥¡¸pƒF±• ·°dº™œ%-ù q)qûÉ…þœ¥~Ï‚ƲÛoMÞfÌîÖø=Þ™ bÏ=\ü€ö¾~óNþíR¥kTìQ”Ê°—›«ô$<ó‘:1Œ¶m7~ï^aŒ]À¸ÁÖ¬zý Ë çk ÊQDûû14礂ƒ¬&“9%ÊæQg”@üx<àüÀã‚#/IèZŒð@’Š!#/ f>^— ’0LzWyg¶–ùÙH<ïØ÷Û–pYãˆ÷mþ"üœž.ˆ‡!Ù|,žÞþRwȶ+è˜C‚žÇe}Ïd©i¼\¥É‡Êü¸%ò k~Ç= neå^SÓÀßùA8VùŽë1{|"7¼Æ‡Í¼í>yDÀ¶1Ó?›Mô£r|.: n`ïZÀèðz8émÇNÕÙtðã¬v×<®ãŽ(ÇmYŽ…—¼¨Ù¨mÖÙ*e\£·¶xé„í©ç7GM½™¡èår£Ãaºô¾¢ëÛž=q•!†çœs$D<¥°p_MζuäÛ;Piµpä_ †ÀþŽà”ìØÁ»ô»cSnæ}Ñjv£%‚±Ú·bÊR-Ѷµ˜kS¼¨Ñ0¤÷"(ÀZ"¸ÌDy^Þ­š›¥ÔW°c•˜`S>ežÿ~fì:ôÞ}8à ,L†êyA ˜Ð .mý£‚uíá&<õÏÕ*jòð¢„G·³€ž„Ðñ>º“ÔP!Ÿ˜}>e!õûR¡ýDÐì9NÿjU#/rá±°íÛ«t°/¬Aî îlKpAªM–ÃpZòd½YòK[?i`ë¿Wûº°#7-ž5‘Ñ&˜òî6·6(LlçT#7fÇ=ÎB:ƒ‰!Û(2nrS¯"-UJ– ˆ# ‡ggŒû9ï’&peúTÉ­‹.ëÅdFÇfšˆÔ;ˆø¼Ë|¾Z'Ø÷! ÷í¨`ªA0Á1é êdšž9ÓÛ^‡ë{zvéÐ66í.Å5c^‡CÞK#!ƒ”Ù;8øY:a ¼3yú‡‡CÛôLK"‰d9â¾^¬7íî‚$FKòŸÙôèv:úÍ8oò5Íçáe¤§bQg¨åC”­©µ4{¦¦¥›GíñõdG‘®¤‰8¡¾Ý/„•?R:~®j}S¥‚#/•Ý›=¼vVLÉ›r9±Cû~|yE„¿Ÿ ;ùR '¸ˆè:e0¾5¬ó«>‘õm¶ý¼o ÷¤õÈ$ð»èW¯r†áR›Z£E™N`”ˆ‡ ¢ („H•)FœÊË@¥1 Pq\$Ñ!RÃænÒsVü(¦i#/ØÁÃë HI 6aßÏÀlÚœÀ€ˆ56B¤Xª:Gn´Î…^P‹È¸•KÊ'Ðo—SX’(‚ µ‹)´P‰9žgDbj󫦹TÅU3žô%ÊßN™ytD#7¬ßymá¨Ù#7ðˆ”ÇØCîäþÆÓu§9ÞN½5†a˜:ͺ¤+³_.åÎÀéG5§(Ѐ fm98)kÊ•Nì£õßVö’`Ç÷ë®a‹:”6ÖQÓÜàÅSm¶Ð|áôqpë“ic"‚ã]‘-nMÔ6Qxq 3@Ca¯#7J´¶*xÙ#7CP™8‡êÞ¤ ˆé€Q(!¸y„±4'D K;ÍÃ’Y¨†È=#9y,'BRtÔJ‘Š0%‚Y"q{›Ý•êøvañ¢Õ³žåZŒ÷®0ž‚à© Ú£BŒ%éägU:#ÞÂêp:ºv¶fãlH‡H‘€ÈPHÙ¬¸†í¢…10¢„ ¥žf–´e”m¸yE±‡7#7²’X›–2B–’ú †°034²„Ó‘AŽH¢¦ `^f*™±‡N´2vt†¥¶ˆ¡Áøü§q#–ÛÖã¿S’|0¯×RpŠ¥Nf+J(X„°8ã΀,WÎæ»ìf柬|ÌÑ•#9A¶ñ!£ú³ã‹ê;´—4èm€¾v#9x¼ôq%Û¤¾x彿¡ú ¤ƒê=@ fI„™[{÷uÿÊó»²=ŽÄ“K%ëºBÎ]wØä}óHrgêIÆÎ7Ö#7•]ToÜýr×lHY5½ŸwãôÛè¿{#7`ÖÍðìÚ4pêKœåÖ.}•ßf²0Er֦Ĺ².ñëgœN°;xØ-&Å#9©T(âöÇÑì?ÌeȘC >SЀ"ÆÁ‡+’÷Z‚ t‡˜3–K'Q½; æ=¢Tì‡ÇÇUE$ŸDÎî7’„M±¦1±V:ª¬¢|‰’ŒRd²˜æ¯‰Ì<þ_™ºÆùäMHž›+ D4,BFØmiÁä`f³3€"?0$ªiZgX‰¨73#7E³€HßÒUš2ºœQlM#H“ë§jÝj.½«¤ªó®¤‰,yõWB;/o³@yBFÊ…6d~ÂÛ‡«\8 )ÎLˆuJI'¼<ç„×—g‡‘TÓÚˆ$ð56rB±Z1xˆ"ŠFÓ½ÎQSM ù\£-q€ðæËóéN̤±V‘ Û/a¦Œ0‰ãiïq#71-äÔPìC® — f´ÒÓטnt T7Eö˜’+å÷Ù˜ò(ú\ŽIHÈÝ€v(´BnÍ[Gj­àv³Â¤F.ƒ‰†ú:“-²n±ç_Hd¿—A¶ÜmðYϧ9,ÀË$™£‡&јÅ\ˆ#9…m#9Žëäxa©þÆ®€ ¡‰ÌF†›ÚfÌF=OfFŒ±B4ÔµÀû|u³Éë€ÁpÁ‡ÔóMzÚÆb^QG¬QĆ½]#9T¨(ÆT½‰R%#3¦Œ®bkÙ¸pÛl0KQkI¹…+J0¨¨1E kY/@®¸úëRÈÒ9£6sCg,P¦c]3 ¹XäU^Ó–64ÁQq¡¹#7š•µÍ…vBu¨«cZG;çôvÍõgÚyÆ›í+|ëo2|™wè¼LGª=ÜÔzÉO¶¨IŠ.0°Ñ«Áµ$ï^—SJ¨Ä÷‘ãwH*NèªÕs¾²ÜZë ìŽv§}Ó£œÄXÚÅ‹ýi¿Ö›!„P›§}0žÚZµaÖÉ#7¡{;Hª‡(,ÌˆÉ V1$®F)¾Sk5«ãiqTßF\•”£’Õ^#9,ìeVGaÙ†L—^^2ÂRª‚iÙ“€’lÃ`ä`½×-N …›Q˜&S bRÕ£a Ó!¨Ð¢²h-2ÃQ ³#&̓—LLbíZÁC¹O‹M#9˘¢É/®›ŒO°šÍ9Ÿ×¸ŽB™òòiðã³lÇJ‡Œ?2s›Ñ;V_¯}©aóo\#2ÕÖ"3T†èÈcàÙœ¬¹G"+Š&‘¶ r7¤ùym c4 ÕØ42ê:ÔÁ«ÎlüÅ_ßïû:Ÿ6ô1˜o‡ˆÐH†%€d#/òè a=g/»§÷Â{¸›ß#9Âq.p…À&Ê‹ž @LgÕí¥$਀Âàè³#7,"HUš‰!rcGL’G1Õ4! ARI¡R òéˆ80µgT© å &D1#/á3Úl6tà1@j…Ä‚4Ù‰$4í#7Ñ7EMÔ;zy‡tü M®a8q›ÛÁ9ó>gÏ°æ1>H|©ìëb‚¦·˜®éW»5…ú€õ1´ ‘\í^8ì!+ÓI¾|Å?Šs83¥®+V\}&š9×sP5ž>Ž.Žeñ<Õ‹ÁøÜ&œ&ý¸ðIûå\™ó)¥SmL¯ZÍý7#òúØj=‰"‹±ë½;›+“‰Þütz•OÉDA!Mh©›b¾uÏK\Ñ °6ŠAJÔ¥#’¤AC@(Њ4¢´ŠÔÔ£’- ¥ ˜b!„1 †à(A"õ?'AôüVÂx’¡·êö¼8cX3T æs¿\’iK(@ ꃩÓãðNÓÆ2jïÀã]˜8ŸipD€O1‚‚24"#,É’™e©šdÏ°ÝI¥MQi3%\êLI’ÛH`ÅDÒ¦AM)¢&[Fo Ü׿na“Zf,“D¦VÊÆ1fbJDÓ62b’"ˆ‘TPÄ¥‰¥ò÷Q´–E#9#73#9IIfdÚ˜Lš5•Q"™”Â(Íb´Å-™D¤ÉL¦ ¥*LÄh4ͤÓJE“H’÷÷|•Ýú¨œfïu1å!YK÷#/Kgºr×@b×éejªû©|!nÌkåýWf„xìƒ\²m3wHPÃ×ë8–*r°ÀKJŽœ±€ÁÙ¸’[L%ˆ~ÎSƒbÌ)4ÞúÌÿpÓ”4ÈÄg#7Žßˆyò¾QB²˜ÿ#9>1†:ºr0üݺGrÀþ³2F@°e~m¾äœÈyhM|p‹d½MiüéhºD!ÂëÂáÓŠ/3B ù‚æÝ‹Ò‘´Ê4 o~®ºÃI?¹Œ ÐL±ï§Ãì‚öT°»ñÄ/Jh6&Û pÀÈèÐÂd© ®ÉpóŸDäp‚'Aëšb$¦€™¤ ¤‘²³,¥¨ÄlÆZe˜ %’™òã\ù÷øx™˜˜¢ýµ›Ö%tu…OºT{3ìy“•Sy¹Æzôa#9ÒVvˆHù2#9g¿PÁŸ{·}å·ïŽýZt¦p0˜méú 0^o¨f#ðsa9#/^ÞÃåô§ÝÁy?¥!¿š}õ=C‰¼RõÈPõ¬àùj.oùþa‰Š8öri/bôBˆˆ[>Æøl÷+Ù ÛÊíï¤ß¿±¥˜@¬+H!„”F’€—uƒ/£½6üÙèüø —o½i5{Ÿû2ï«÷ÀóÓÎ(ëŠF ¾çÝUUÎäI*"g¼îSqOœšb—xqî F•áñçü‚W¬Mš1–´½°Zº#9¤–Úm±£ö¡qôâÍÙBiÒ‰]õ+{ëŽ1ï5k´„v ”©ZlíªÂúÙm„<çk”4₶ŠÑÌ0º#/fŸdÚӛÈA²Ø’kä±£Uñk|˜kPK¡BÀðs]IµØZv¹¤¢ xg+T¡”Ô DqŽ¥¹¦Ä÷š5Ý. lƒ6»™ä¬ ®„Ð"¥=Kî{žv§-á$Hµ¨1䙚Œñ¡GÄ#/:Š_rûà «²lyÑã4›Ì€Ä(Ž¤ÄÑ<Æ'a\îë6ŸÚc›ÀTœñD£ŽÎw,Bnb>¬£¡”¤$ŒÙ‚f8wâB)Ø!ó‰ï=HóËô}7M&ŠÐô[rL€!U@@@ÊÝ€ê#9ÞY¤ÂºúýG@ñò³óúýD`C zü?:ìÆ?¸ïµð‚R‘Þ›J\¤Þˆ‹ÐG#‚¨•óhAº Ç¯“õxPl“ñý-úBÆXÑHOE;ôæûöá3·º„+‡çï-~Äïé_/›GhÎDL³ŠB‘OÇj…°Y¥]£úáÌîïâw+ï<7;6αã5ùó,ö©'XAd’Ny9#m˜À˜ÖpÌ.DÜC`oŸƒø?QŽ>í9¢ºŒH 2#T@êW@%Lì_Å[Tc}¡àl°³gœk'¡T#9«s’K?µ©MÔM²$ò|ÍÑ“Q~[§Éãz¬Ëy5¡ä„š©AêX<®dó"ë§=̓máÆfÊç×75§Iœê<ÃT™kmšxï23Làj] $ Æ3FEZ’’ØHbã!­DH²Åút¿‹[6lÖf;Y5­sîò[¸4UÛ%Xz•º”(%©ñj ž»µôc¨íÐ*^¤Ùty‚Æ §„Í…;­ˆÔŒNË=dÙO¸ã›fRqd·ÂÞÏÂ$u·ÞgS7nP mŽGdÅÖ\å8“F ÖŸjwÀÄí“­#€`r»£L‹Ž7ršÕ5Ž¦¢€La;&šÌËIÌ3š&Nøä馩•$T•FŸ\;»Æ0µòÏyÛ)í©·¸K=`:pa8 ç¦¸â,uÄq&_}ò ém™g´ø袓0!®4ÓS±gwf«È„ ²oµæŒ¨©ÁÛ;HКPhQ¹ª˜v;ñü"†ñnåé¡Ø`׃ê•írQë‡D³h‰Èö“uÉñáAéæmœ^¶Ôæì•2Cq§<5œófÌ÷¬‹$RÖ/}Vg&µœAŠêø§qn= é;¤Î€tî‡Ò6z«vôÙ,¡âxô£mR›XX(KMÂÃ^Œ\ÜÇ-yr´úvÔ#9ö±¥5R Œ\D†ˆu#/ŒE)i%6U–B‰Lò=D?$o:“8X¥'çf‘ù§X@8†å…l‰ÛC·ع11N!\L¬+º"À$Ƥèzeˆ ,8XÛGäß×FôqÁ¬Å/´„ÒeÓ'Ù’Ì-í”ãÅ݆j6Ú9²Á¸Fúnr¯»¸š±o/=Ë/ppÖí›jŽË8ó„5¦1®Sœ[O›s0¶ë4ß^#7ÖÍVÜÙÕÖžad8°¹üçv§Æß¾ÖVë(“U3(d2SÏg3±ÊäAQviJ @ôž_&çzÝ8¼:ä[ ²0Ýv=IÛƒùT .ÌìA¤E¤ j0âÙÌ@Ž$ŽdÃ.x'‹HÃÀŠÙaÇ$Ž’3œ–A&ëŠC½@ãu2…¬9ÆI!šÃ©ø [ç”>FË$sxÕ¶Zˆx`ŸÙÿEFV;Ä p©ì—nÚ2u+ž|LŠVŸT›ïŽY ÜåœÒaÄÎkƒ <ïÊé&¬#7P:±yÉ爓Ô6Šôçh±šz,®²óžð8èOѺï#¬ñ:nu¾P¸F†ãj¼ãfcNn'òú[!ÍŽ Ë@:ÃбŠ!™Ũ mà…»ìhÚ°2¬Fvµ‚bÖÄj`Ó—ÆU“#7—Þߊ~ª@4LbîÅﮬ]"ÐÖÎðâ„-šêàˆ0pæR9>vÄÈÔ¹äõ;•1‡‡Z_*4¬#‹£+@;ÁÆ Å˽«½°‹¸3ÊØÆ›,°Î¢…h#7Ô€‚ŸtÈ/vR;Hôa˜"„ѦƒX{û‡QëŽÃ\œÃ!C*º¦ÞTj…$”ÆI™’š”6$ 649©†ƒ³*F¸ìÍfÄa8¬sdÅ)¡ÎQ`nÄHÇ ’ÉP9qœÍƒ%ždFñÇ$hä3³;Âf*†zŽM¤°(dXÀDÈ ´ÌÔçFzqêÉ0F ‰†Ìnéhg4g.3i7& !Ɩꎃ ä4,N£‚niuA´f{1Ò¶Ör@Zy·Õ ÙSmÌ;HI¶8fÁ,#7–l›Øŵšf¢Ì5ÎKaØk#//+ÆÔ–1=G{›M”Ë jF–ÜÑ€–D3a¨`œI2%‹„°9¦ƒ‘v@‘æ°Ã„Oi¡`Ž’R¥l™£&jÍûÉV-RI‚‡òó0}%JD(`8¬ s@;ØyoŠ¢Û &ŽÉ”Ö˜"09þ^Ïêó¨þ~A÷y<Ä”!—¯‹kϹÖ/žò®ck`–©Pû³óúÇ#/â0· UÞé|‡®)ºJtéò‚¤J":B%RP¢$q!Å`–ÅÕ #ä @Ù k#/š@ j‚\$€¤à´÷å¶~EøºMƒ±ZONâÌ?‡ã}þ{«³yÄÔìˆUÝåŒ?êšS¶HÚwð—ŒYô™zmpÿ$m©œw¹gW×kƒW)LÖã&ìê;¬¢‹’,í ι}ö¸qB¬8ºD6ró5Ä!!A+…—ÅASQÅ®x½Õº©•Sƒ‹;¶å“ÔêÎ/ƒ‡ä#´NÌM(W#¬9u9•8‘בus’"j IÖxz@Û³#/E†çƒP#9d;Nh¸:ƒ½Í*I2=#/îCÁ ìónöì(‚]nÝ8ÑÔ¤®êúmvU¾ª&bv#/ÀåÜlhA#7Æb1T8¨ƒ¤_7¾Jç #7[ªrÖÈgË·¤ƒ#7Hnh›NÉ8¥]bj J£­z’@Ѫƒj¥Y÷}Þ :>) Å`jôßg}ªþ(‚ výªC#/Ÿ$d~Ø #3#/ÆÆ·]Ù—7]7l5Í’¿P¼BÑû\Æ(G‘»©?QÔù ÷"{¤_4z‡È“ÖMõþãÒ?ãgÀ±ƒ¸|D<_âÜÉ ãä䇤~¢CÆñõ˜0Þb5†¬ÝGrSê7¨Ñ!þ€?±¡ûþ{œ¤ú@:#gCøp] OèÝ>ƒ’‹Fè'‹Åü΄>]Ï»·û ûÙíõrÄ=o!¬êB2¾Ž6öªÌ×v94˜¸KƒD ’DdF³8ZÓH¹@l¦àÝT…±Žƒ¢@ÞéDÊ9ÿF†ŒÒ)`6”sy\vx[Á¤Íƒ–ÉÂzÒ!ŠsÄB\ÆmˆÚB^? ¼þã-èq2:ãõ88§Oç$6#Ù~ùøüBI •!Ñ€X>È´Ò’‚Å¿@í~“èÃó@z䔨˜" …­¨¶-HkhÛD˜ÔX™4Ì´V#7ØÍ/H%!‚)©»çW·„Ÿbl}&êp~(å<Ð}¾#/)Q”×­O7o¯Þ¼àÀØ6–*è{a©ÏÚ©ìBô™8eΆÚÑžÕpEýçj^ô=îGÙÎi×5|eñaK­=-ë+ýÜZÁQ¸ûlRTt¾'£eËÂI+¹¢%´qZñ1¬ïv…²ÕSÔea\Ì:m)B%ôÉó)ä}eã6ÚM”6V¡J„Ðj iOZQŠªºÕB3SŽÃ0ÍoF#9DmYÒÑM¸jâN2 ¡ˆK,zfdÎ2L¹Ãz5ŒÕƒÕl£áhͦ-ê ­òôŒf3®•mÉ¥ñM9ÂLñN“tDÜÉt8Å8§kâT8& v\4×Ktá¬mõ528SŠ¯iJ§9Æ׃LO‚"#7àÚSÜn(¹éáΖñV›ŽQxg…„-U!®\¼N®]™ñ·2E§vF6ÍLUlûÜó(œÃS ’ÍnºK¡[á“i™Çm£P´ô·˜ œ›Ôò‡›}9ß#72É&œj+¥–ÕÚø>ƒ5#9¤Ìù‡‰ Òœa]>ÆšÉca5µixzÎ_S‹°ýwMÞ¡üײv˜ùÙ]MðÀCúô¨–m±3p„  €Ò’:aˆ m¦@“(ebD`EשúÞÑ-¢÷ð¾Z˜m&BË2?ɱyÚùa¶³OɆúZ¥À¶D‰ºa½´¸–»5‚<«kR¦S1ð܉€ü8#/äJèë;ùüÿÎ÷öøô¯sÂ|ÁÜ4Ñ>î§À­‚à€Ù3*hnœy«†³¸ýl×’¿„džîÙݺøiÃl1ä c©ËŽ7G‰Õ+ý~&Šx³Lnš#9Ѽ¨xÀ¯QŽœ6‹lC0ü¯ éGàσ>Å sCðaÓ‘òÙœ¾FlÍK€IXªÿŽæ#9 ]†*P‰ànr`Λ3‹Ä_¦Ô@VöD¸Ѿ¾? ‡èRŸÝH#/2)#/B¬Pþ©íüþ¤Jð>˜þÁkK³öx—5HEöiÙ‰düÒ@',é±F¿W÷šÝeMÿ»ÁT’GofŽ#/ A1P UŸÜÖ§i"ñu(›I{vº¨‰’Mãt­¢*P–š’Ý*ì˜Õ/)U¹4Ú[¥´›(ØÔŠe,ÓRYL”­1K5 ¥")ou…,šÚz›³~×¹SiJ*bM¢¶³V¦‰ãŠ+#HA˜a(TGz–+!à i( AS*¬£-JkRU@jhÆ“*¿8Õ]mó9Ư‡vÉ5í.Š*¯p­j¤I0¶šÚUÊí¦Ñ¤Í³dÔ­™zó«Â•i´ÙE0ÔÕ…ª-–ËI½;mj)kÅ¢yÛtVl³Åyy;’R­v“BæY®¬Õ%x.²×ŠëSé­®$m¼&»µ-¶–T5p#9ëÞýÙ¼J#7»†0kp»'ÉÝÓ½¨ê'4Bá ^­ŸŸóü!õyÞž"}d‡I;Æ7B3×qy5$Ñ8e;túxÁq³„ȾÞ=šXŸuõÃñ\'Y#´º˜Ì߆îð4já4ÄD#7 ¼pëœI#/š« O~éš–›K ¦´l¹dD€A„{ø"hç›nž…Íd"6³JÙ¥mìª×M @Ö02F›‚Ézf  0…Z%¤hs»JJœGÈyc¥}Ž"§"•b¹#/ï(.C -,ÐB31-_v®ŠJMl¢Š’²L£-I”6ú vPÃe¨¬¬D´bQ”i¦É#946›e)¤KISFÃLÆ3)Š †Œ­”ScdÉ%‘¡cRV,XªR¨**SeJS&Mdµ2’© –HÚ”Cj6³i€Y#9RbÁI”˜M2M2T²¬ÛÕU‘#j)bfÔ™$Y«ZYV(Éb’"F #/†U•PØE3RA%"X*H‡‰#9&Ë#/$4 Ä¢¥ pÒÆð†J›2#@#HDZ Í+W*´‰­iRª&Y)'‰þ4y¨ðº4ËÔ?#/ïœIþÜsÒw—³ÃŽÐrRrÄëaZrÖqºBFs ¢#/‰ó¢€à=5¯mB}ï\bT'ïì.±ó:Œ ‘†*sïÄÎ#9ûÓK±î¼¸*Ó0ÿ•7LOÓ3>ü‹Û $uç÷°øã÷§FqgŠ)›ž3lK#û<;±®tÝ‹f€Íµ”1ç.Ž­¦†KÀ䥴”;¹T¥v˜—Uò¥¯r÷và9˜ÿ›`Õ‡¿Kìdz®PèSù#9À‹ /¨a!¼! p)ÌækHƘÁœœeÁ‚R›¯WyóÕ}*—ÒÚ¾½#¿qý#/ßT€¿ö _IÛ®{dwh||CÒ*ƒŸËËÚ~]Sß·(NÈ8Ç'É¡M5øQ“3?ŽIù¿‰ÅLLc1š B.Ý"[¾»Û 5äoMcиؘ¥Ó/0à¹`Ã;A&…#7Ô³D>”dŽ¾Eë7¹ø6*Þà7P -ߨ¿—Ù3·ß¿ÒÈ„¶vð ]ö¨*+ôâ}5Y/†eÂ2²üÛQ+!_s‰¿^§!¾`E’FvaU&•#7ú¢¤=MEFJ¯+’£bm¬áŒbz÷µ–Gl£pŒŸA‡=ŠÍâG­›,Kƒ}aBóƒÑƒ u!– êH…R^#n¾Å? †Êï‰eU… @òî#/#/dÛcUF#7·Ë*î»nCÔáìêßDA Ü1O9t ò°R¤´#b›ÃÛå/3­¤÷ÉPá=i‰?½ür[áâ|¨pE`){³ÐÚ‹±ÚtNÝLµLÒP4 ÌIx‰Žì‡9g|Èpm–Æ"u«*¬Q&æÛ5˜ïKÈHL dñg[;P <ÀÀ99SvÄI‹õs%B8åÅl^›Ð#7Bíõ%(¬Cck£èƒ‰<#/5ö÷ß™ˆq¼\çšPWz$?ƒ@ÿÊÿ8¶\´uÈ…‚Š#9ú«,ÂEµ¬7æîœQ‚ÆœÕE ‰°2S!Wîþwnì´Õu«Kº”ŠÁ-,ª#/ÎÛŽ:w“ ÞL7ÀÆ2 ©Hà÷„`ÍNŠ¢ïŠ‹\46$Ø#7H÷`±¬i#7¢œB4Ú¨$6ÑΡ‰¬á¢Æ,6U%…îËnR)«L¡#9­k4æ9µŒbP6ÒV£yŠÎjÄsBÅF[ªÃJUdQ®Ë¤“KV‡’EºèʦqP¤1.ˆt_×á,Ù@„¨ì#/YÚ'ÓÎ&º<¶Ã¥‡ÆˆþETéÍv8ØD§™šCsç´ ¨Ð93ݯ* Ød¡2Öã¤R4j’±Ì#9pyz$¶~†ðb=QáëgŠx”׫ëèk±—´ú“Ê`ï Îb*†[6&ò2ÁË•IÛѽ[™‚¶=Ã9Hußk-¥6P»H‹®ÎÙ§tTíìëìã·@ÿk±]Kìèç¢Ñ$} þoʆÀK@^‘J,å×úŒtïð~àm+Ãmm°ü¦ÕÈÔ·h`”Æ/îW‡äw}U¹%O 'kYŠ¨ikÕèqɹ$hXKÍ8B÷¨JŒM •ˆ‡q‹æk}QÌAÉÆ„ïJŽíkßi0n‡¥³¾ ©P!+]¾7‘ýû˜eõØçmÇëù=t{ø1æ€ö!1òCwõT…>9¯ °uN~\¨?®“ç$8Ÿš¤th:4L‚;Šð‡Œ¡ÉWùpÙÔ¹gÝæêMñ®<ȆfBcj$ì`°àÉ-”†ÖYÔ§ô™'$À½¾Ëå+`2k[Ô•ms¦¤(LxÜ¥†˜„i¤˜Ä@i©IIâ4{|÷Qƒ!±¸MÄŠ9ŒdÂ#/tżà-8·P¸0ëÓ:õz6a’22Ë·V 1Œi B¨h‹)àžMW"½·Œy˜¢ Óm§ð¦<ìOYB¸9“£çEÑ0jHL”âKÄ3ÔGQVµ:VK¡×JÒoßÖè£Õ~ø ª‚'aéÄ0ï•#9*—«(A(“Ë2®3>R=ö·Ü¦|Bˆ˜#7#/Ài `¸6Ay…½Sp«á(š&(šc5 2©2 ”"^1!XõgÓ÷vö¡ï;þιÊ{–èÐßÒ¢áuEäÇšpò t†‰B›™ì#H#9IôY\Ý“ˆ±5Ùã Î-'Û¤ ÅúwédK'74Lv.š! TÌÑôH#9CgÉ—® vqEá÷ñYâ”)µØ(ª;-­”]éÓNHÖ2c2!v½Pc+vÐÛ8Ø‘0ç@ì6] §7PÛ´<|°^•S^º)W'¨½E€xž§ îë7•³<• ;ÎèLÜó£¾wIÐ`¤NÐj#9¢È €á†… B`F!víÕëèz»0<"y:c*D1b`ÌqHT<ÏüY»„Um.™ZO«çsklá¶P̉K¨€úh¸„¼cO#/Ø(ih#/äl†ß&ãÆy‡Øøw”¡é#/ó(‰àv˜'=œ¤/¼$Lj¿sFCV±ŒÃd1¥¼¶pO¸œ’É\*9ÍYxº4c° ú]AÝïkÎ|;±œé3HžÀÒ+]S‡Ùu˜Í˜¦7¥S§½½|›ã\™÷κá5Œ{x5#AAsÃ*ãÁ>Îw"™*zaŽ°LnSËI†Ö6aª#9ñwW²¼kœÜSŽ…Ç™­Éf—<ó­‰áçgÃ×fm2ÅLH¢ ”’#7C8kX7 -‰ÕƽR7̆¤ÐÙÈ0²*¶Žýc`Ö5P!;£)òy›—ÐcŒ¯tî“ë߆µnŒ†°$÷ ON' g®Ó¹X@šÝihžXRºVv#/”X-èf#9ÕÉ`„#]ÚãY q¢¼o°wÊÛ298EI.£³ÔMÝúý úxb'ËÞÃwOßoàLÄcÕ‡¿å¡ðW®y‚B]eJ墉ÙäÏBC©Ë: ‡»]˜ `ŒPg½¢à꾎ãF¡x¨U¾dŠ²0û¿LJî¨U ñêúÔôlYÊòÓ Øl‰Ö6É'Ã1VŠ#X!ÂÈÑ‘šœeò²&(™X’'^¼ÛÖµëWY$É3tˆÉ#/q1i¡u±j¢««›ÛβñÔîÜRÛ—#CL`Êš£hjÊD«)H’ ÍuéåNðxŒ‡úˆ{å~£u;ýÝz.Èvò|­Ëú;|Gø¨€J<=^ñ‡MŠøýOw„ú*4ÙgT>uò<ÑCGž8fSžýs2¯ÌÊô¼kë8°Š™a ÂÀªN˜´AÃl›ì³^‡yfnN×ôÛBHwæK¢~3ÊÛxÔV¾#9šh¶!(Éi€%’ÆÄ–œÀŒ(Æ®‡3Y‹Qj5_xÕs5‰*Æõ5_QU{ãrQ59*C/ôEf¤ A€$6‘pÈ°¬&‹]M&öÁ0õ,û8Íi¼­¸­Äš‘ö›†b–MBRòš•¥u.N0a#/@I©;`É¡ cf‘FO½#7 Íg~03$ î44Q0A÷®ä´ƒÜvœŽç®ÙàŸ]a“ÍEýa<: b˜'„sˆ“¥Hê29r,Ì? Ê¢uU>œ LÖR¯µMÓbßA¼¡í: ôèî<½Ÿ&©?É™ dä¦JI.f HÌÓCC4©J#/ˆ)Ð;~ŽÛ=ãÈÜa©äÚ(€ëZãfòˆØž`×Éå<´9ëڣ瑄H¼é‚~î"qØAþÑ¿Ãoºû<_¤<ñÜÖ¤ôthmþõT–‚/Ì`U bx†°þœûI#7ö¨o´~Ÿ¿ýù„ „“b™·* §Àê7Dóý_qÙ¿ôðPtq$0þ¹:‚Ï“X.P<¾?óº.CÚwöw²1¬âQ „…*?Š!û;?xê " ˆ¡"ÔmR#7ùE‰<Ô1¹|ßÁÊ#9KÈÁ ˆ5”J‘ÕÀ3ÝÖM¿cBz¯‹Hðíà=Ôó…x(«Cšxy>29€¨¨:!eŸ81#9ã\ïg(:õ›:u $ˆ)èìfX}Üà_Ž#/h4&†~ ø"Ù79ÛªTª*X“ÛÞœö#/}¿ò¿ß=‹¸‡«ãÓÃøÉQJ iPõ’ŠYŠd¢& "Ä#/p 5#/ƒHA‡!{…ѦPMÊ%2¤iHZt’J(Ï“g,%õ:¶5™—ìCèãqƒ2WF…b‚ÓIbë¡^F`Ù õaìGCIÀõžtóŸ£Gè} ÿï!Ø>=U‡¶¿ó¤2v'Á>„ÃÈ<ó’¾w3öEˆïóUAJ”¡Ü8B~½¡|M }Ì–©-%"¸iyHtúvµuâ}V+r6ì"fRëê§åò¿zðaß%C fŠöU LÑ7o:Ñ” C‘@kÛ?ÌO˜iEmãã^¶à:Ã]É‘@Pw#7¡›cð.Ò ™ê %M4õéȇÕ<½Ö\?”ƒXÀ!ç Ž`X¾¡H.éÖïK´µñÚ¯ª#/ú_€çÛÍ~ˆ‹!BEi#7êEý-e‡ëfdt¡þgj†Œ3U ±QT*l×ôZò8D´Ðpë›$`£Ú9¸YHA¼ê /¢\ ÚQ±óó2ñýT–ÆûÁÆ ëÆ’Ι«ðÖêJ1°ÞàŽªñË;³Ž*I”UŠUµË1³’ajèÕ–a2¬é&k-®%ŒA¤veh1‰>4 Æ6‚Å&&:A±¤[U›Ê#71´61™Y+@F jF¡51ðãX×V]TÀÒE#Æ2@á&rÄ „¥h¦‘(s›ÕÂlÒEÎh0†#"ì–f¡7çŠm ð“$*i7K…°Y4a @´¤¤ß6ÕÓ£L j–Átr¢ŒÀ˜e¥¬ÊYm |Òë³»™ÛÃ#7²*ÅZ1‡F£Y©»µˆ›ÕZ ÅÖAÈ4vÈzøuW‚#äîéݹl\ÛFÒ»£F¢´W-ËݼO;’g®¼kÆñÏ]vßA±ƒ\ƒÈrÅÃ9Z›:È.Zv‰cXÑ2'Fu"ïþmfe„7ÉpÖ¬Lhïot4‰Ú%Ëá Û’5cŒMѨ‰…­mOëÈc4Ï7Œ¦Eã¨à¢¦õCT´‚! Ž“Z3Š×Nºï‡/ió(rH½CùÂz°P8ñýgmàéR_%øÒäƒhq‡¿²pŸˆ{úU,Mú'&`šubšÃ#7 “ƒ80#/IöÿÿÑŠc#75ÌØp…üÞ̾GŸŸà½’̇ÉÊäéè =oªësý$ûÞ’„¸ŠBŸ@<ôJ)˜J@HH'§ùêô+m;£Q¹z¶ñ\µä¹´ÔÍ$Ôšk–òi6íQ*$ÉrÝ&ª0±X¢è‰SV‘h)#/°3"ˆI$bIÝ0””cZs²ˆ„%¬¤&H…#9U`$a¤í0ŸÍ ýàâDs°öSº#9sOª EˆBn&ÍÐþ.!”&ÄZ`»Ò¡Ä´èé¼qG9²K* ,‡ÒO±PP @àè:Ï_‡Ò¼ü«p‰›ªÐ‰ª²êQ#9#/¯Ôª©› @²,˜|ö4ž»9º±y<ñTc=ï3¾ìNƒG‡Ñ=xVWJ›#´Q,¹nù:]µÈ†$€ÉÅïX‡÷1ý ›ß*dsûÆ‘@9áÖ27¯”?)ú<¤ïwØà>ÄÌ;ú»‘{#/÷"2‘ö®‹êÝ÷²ÛÆçWmÜRF”´¥!ZQþWìÖ¨42âr Ť-õÚÝrëÞk¨Ö"’)!$™ˆšÇo»cÌ{Op;ÏgŸé¡¦ˆR|X|ZËáÊûT‰J¸ `ñПwÍxEºŽjUgoä_³C)øIòØ=GÃ,­«¤ŸÇ#éÄ>Ä …ˆí§ø½¦*Ó t(¶w—i㵩ÍGÉá¹+´Ýo¾ª/ a˜p¨VøBA„:vÌÉOÅG6uI11¡“L­¢†ZÖ81†Úª’ƒCLGr`ö›Š>Ã@‘¢†…° ßlhr#9SBؼ@þ‡çó€ÄŸ+í='¯!Dƒ#9ª¤ŠÙ`ù$ ðŒ$˜üt6›Yñ=åß˧~Ú}?®uàÁ;l¶ÍÆ*¼·èÍoüY“2A´¡ÓµÈÓÎ6“TVX*jCuþÿÛØ"žž‡jIµ±Ô@çíVg€3¨é*äÙÍ1¶ÇŠÓ¬-'Åá°™dóÖ¬Ã'%pþcž€ÙM”Ñ gNäžµÜÛ0ÄfÍ÷Î+ÈÔœ á&ân8„ÅaËfÈÓŽüí˜áò*!_¹o=WçÜÊû`j; qe°ˆŒ07V´|Û;82¨áÿ°uüµÓÖåGý᱕uš”Ù¯(ƃ —ã*­Øíá®çÖQ­šÒþ‰Í­ŽÁ?ùCàý ÃlïèpPÑ÷}€9ïIÉ{À×Wd>$‚„ªJ¤´ÑÆ#l‰´š4•#4Æ+SjËRj‰j21”×ÝJèƒA¢eL”Ô³ð«lÓ+E&iŠfÍ*‘JZ¦™jQ66–Z›@D°2À@„$# #9È%¶6QÅMX"Œ²-Y¢iªUÕFØÁša"¦#/–àÐû¿k _¿Š+ý.?nÉßݺöF¸sH“˜ˆn«ÁôHxu0ˆ%TL $ 2iL T2W"ÕHi¨#9j—ó©;1B‘!ö:ïBOHùÏG!NðD;1ë ™dP›•Š).¥óí-{}2m°…ØBõ´H_EŸ´Íç•ß³æ´E.Œ°ÈfË!ј{ È 4|0}¸Áï™·AÔ“(ˆDyt;l“Á$ÉG—3gR›Iróˆ!íÝSã÷'ù^j ð(C €ž@ör>dó Õ?WnΘ‘ü`xÑ¢_D. r €Ú]ˆDÛX»$¤ßŠŸ23Þ-2™™“4MÜ#/èÈdß—Æzó(éËÙ½`Èg$.¯£¤5#à‹ißåS ª6Ô†Øܒɼ}ˆ€o8)S(`×ÄÁ¦µ¾kccCÖtfŸÕÁ! †¿ÂBÉØÄx9šè}›ëáõH¡ÞIë¾ÅÁ¨|ÈFy„£´9÷Wwj2fkPɼ>ѻއì#Åñõ(r{È{ÈrF€ÈC‡yc(;°MËåK#/¨òó¢˜èd((Ae#/¡BÒÀâ}»#7Sú¹º'ŒEkÔEi$4ØÑ$p¬I³ùׄkgW!U‚MŒ þ+øƒÏ×ð=k!…sDU>¨·ø˜ÈEÓj÷co³…7´ëZªøñôE>É>ž…4/(}F[Q°š{p‚w:ßîñ†¸8tá\XZƒË«ßßð¾_˜R[¢ÉXÒ©6)‘kie±¬h6…bA½ÿŽ¼8çÛù>ÅæÓͨ@'¼œÃF¸;ë…kàJKt‘Xþ“qŽS}ëà|`pÄLpuÒQÐÔj(È2´0dP0|~~&ž£=›ÖÁõ'#/ºY"Ã#9.e,¬C*LVúk¯Xõuåßy¼Ö Sø¼0¼S¾Öi ’|?Ñ14®`ƒÊ@¸äÙš04(ÁC3éÄâ†åuÈFšaS°$RFÚboËÏÛöbLU)Œyb`H‹­0rÐCd5¬JZÛ032í¡vJ!´Âñ ú˜„ `]ÅÆ ­Z{®-çS×/ÃP[2cóUhLºÁ!wúE)A8F4¤!¿ ¢`G#Ñ‚þ|¡œï#9oÙ­ž$áI&ø?4«Ër´óz H¼ëAŽÈñ•™Ï×¥ÏËҒĸMœuΘ›:o7#7®L­¤„³#9š¤Á¹xÅ0€> 4“©Õ8âTH”g¡P.6n/U‚•¸ÎB?˜ƒRøÜÕÜŽ’¬càÏxHà³E.F&ŒÄ œ%4$„h@(qðtw0ò÷¢.ükgIò|~Ü_5²'Gôýã€!ÃÑçàöCê÷{30¦€®cL@p$bµx¾“Q¯’¨ÏµÈ|KŽô½ú#®‘Xß!o<Ò„öôGÞ€> ÂgNû‡n³rá@THy{I“Q ¦{{öåµàÔ˜H¬›%^šäº ŒBÚŠ 3€ô#9ôqõé<±>$9ª ÷Jd†Ak2}s„®ŒÙÒP)èÐi¶xAjÂ'FA)H]çžPÛé:H³×v Çh#/‰£85CçãeEs\Hˆaï*…!( Ún"^—l ±7Év`Å.ΖŽ0`èØÖËø`ôDqM7DªT•®LƸ^dK5âT#7`dä@öx}ŒøN 6'àÖåZÖ² ú\–Á#/öÒ/¦ÈŒ‡_fiœhÑÑÌDi]Ü©er(Š¸rôô§¸[¬A½\@‘^©ªCÌÍ®˜?¹9¿cÅQÖ€á õiŒ5Ê®Î{ë9/¾½øÖ똊²V§.P$˜‰ZhË­d-§G¡Ð5]=‘#RÒ°~¹a$qX`ïÏQâÏÌþ]# »Ïl4îÉõàd ÐCžwjT¨œÓSFK8ZÁÚáS‰]3»XÂÝôji£>R i8sƒuç¸1“±ÌfY¥‰OË;ø¨Ð#4öû½*Ôí¬g¼ë7ȇbËÏ4¬š¡ËBòzj¿…[kœæñB!9a±òÎ ÓƒÀ·´ª(ºq… ½3ût…\¿îÿ#9q$|=_lYÊT:#7u AEP”’\â:&a& »#/E@#7ØpÀ’15.–;“c4’*A'¤ßpt+°ŸqñtÆ…>‚#/ÓçÀ‚‰Ûáó^ŸÁUCÎçovÆCÝêæiÇ2JHŸV~½ù'Ô6žrvúQ„'/A×Õó‡#/ñ…€H”h‰;C·iAá!åÖ ³ =9ä­‚jêÆÃi<ý·ÂCj”É­”Ú”ª”Òp@ó>ÈNpâðê?l>ϯ#/ìõúþnÑyöø͵úô=Ô~͘rFOª}_Ë®ñ÷€L4OÅ8ÁÕ‘)#/Â#×mz0À£"jÉ›®×Šï0œ5š(Yb8”J,#IªÒ%(Ä#ÒŒÍ1$ÉY&f(dfš3‚WM‚]HJXQ÷þ>È¢‚õ?Í„9sÎkt/PTƒØçia–Y¥~p¯“3_»ÉÙ5D¤G°•Õ»¶!ÄúÉëÆ‘F6c#6÷`Ðó¬#9X{GGîí#9nK½·‹´´„sEÂÓ.;NÒ®ºâA¦4©#9P2U+€A‹†`H)$j´£ Ìz`9Ã[–Ðffò•©'#7Zl–°€›€ˆ´”"ZKÞɶ$”á‰SfܨMj˜°+55Š-+(s!ËŒm<Š[ºaÑâÈfÙZ‰‘i»kf¤¼#9á¬m ûûV4©QZF!o—6¾1a ‹#9¡lA¥ÕŒ‡K¦GpNÆ{A>p…ÿ˜í°_Qà§{Ô+šQg]&‰ì3EXÇ‘OOÃlª¿Ð!(#”O£ÏKKœ¡lnçOñ,†ë—K(_£éNFÀ“°ö?û-÷w¤#…ű“5äö•åé›Å=Á@!ñʾ™04L•H‘#9Ñ0´´$JHJŸ{`hF& 0@¾-k#R Lœ“$#9B ÍzÏl·‚½ÐŒüâv¡g»£/ täëøg?‹Ì’ #/0æØÌŠÈ‘Øj„AÇ-C8e€Ø:á ‘#/¤\§ˆ¯©þsà™ù$‚öÁ¦-c–Öö›*©ý1ˆUéŸù-¶ªÃ18ÃCjêÒí6Í—9½ÓÚÃRz-o©šÜm0’odTaýN`˜Âø/ºClx éõ:7Ma½)ôLlœUqM±=ºèE:ñ óŽo†ø›í{&z³;Ì‘H¨Æ3Žºã˯@£]tc¼ù=³|D4HšC™Ô:pA.‚Û#9!̘4%a¶\¤©¿¢*Y˜-¢™h#9ï~E/Œ»ÛêÛçÌÚA!GþÙåžça»~Dpw£‘ÏoZ®Ã'X»y32b µ°…Ê`ðû#ùž‰Õ8ò=¬>Œx‹âCÔ»?Áö=à‡OÍöâXþ2'«K|RP¨ó!ó*ÿ †#/™ú»“´·¿³ËË1Ûw?#7³6|eM‡·Õ×í[CN­7tC°Õ‹,a -ÂhP‰=÷MB:¿U$¸ :àjÇ¢š:ƒ4ḹBKU±ãé9ïòÓñÉ+tâx§8êGè8‡i¼€Ùëùûu$€â§V(Oxˆ½Cñ±ù¨„ЂFu|á‚5k5š]H`D™X †C˜ä˜àÈk0 RÓˆ-ªÉ"#/´”3Œš!ÀqQèC%#7H@+" É$ ûÁ°mº©áá(† }ž^ä¥i¯QJ 1¨fé2·AœÑ—"¤Ã ‘Ã_J‹™6Ç®ø ¤ØxgÌïÜù¦æÎ1‰Öú}–‘ádjC‹˜®!`Ëú4x%àš† ¦9ö©7èÔŠ#7PP»TŸD…¤œ#7Ì&}’Øñ ØlKi œÔ#9Lp“P°:0³aÇ£ç`ÕLH¥ªl°Dc°g\ðþ¼Â¾D=i$?å€2†c7oê.p9g9a®}ì#7 ÐÛvoyÜpaÌ^H;ˆÏw}Yë;9Ä¢$ª¥òù¾:8#9»3Þy¾~ƒ-ÿ°ñ}”ŸDY#/5]°#7Ö~ž‹[¢õtBë–}䟅ÿwŽ#7¶ÚcCmcb'uJ4ƧXãIøg Çs`6皪S‹˜#/£À,(DE5Ôõ”@fEFPúàï—óþâÿOòoìäÏúqg9ñ©}q~I‹ëtÚÛd×JXOD‡ãðˆ±²î¹›éjK䢨‚#¶­±0¼aH~cYX,;B¬VÙ™šo_Ðõ¨:Ã#9G’6ÖMÀ„Äø#7éظ€q)‹z‹â ¯Ž'xm®è“B–çàÝ jd#9ªE³‚N»8ì;ñ ÏÍc$gŽ'’l¦Ž š)Ë-`u>žçÙläÝ«‘§,(ê4Tìú]ßíýþÍŸ¥¤’^ŒÛ…³,XÙ™sÓjÓˆkå~zƒ\mL\&™º ÓKðß^nD¹2$õ‡ˆY•Ê#/è#/¹ÛAc¢ïe×G^HG#PòäœÛ‰xpÆ´õ7’KóÜ݉(6ëÊcJ0èRR5ŒòÃu^Àð"žØv’'òèY}ÿ«Œ÷u×ç#/Ê¿ LB¾ˆA3á†DGÌxáæN'¿Ì§SœŠ›óôöl<<òMjQ2W"Ÿ#95 ùÉ2Uh¤ªŠ´r·-ÕF²c` ‰F•ˆiVh2Fš( Tìg±Ž=‡C’û¹ùa“Z¼¶0Ï8l‘-¡5¦F ŒÒÀÛŒla›a¤z¢RËïôõ;']»;{7nô{ v4î{˜ÑŽÉëϨàˆlÂ(¶a—×Ó`bƒøï’Œ·ô¹Ç<¡lëü'·ÚáÙL|#/={l×ÖÑæ<÷£)±’ CEniÐîÖ’ èæå'qBezCìÇÐî&`=Ò8[7öq;6̲Z2™€tNI#9É*»Öª– |Dö«=¾º1^èöâjd8â$C¤Q£–˜BÀñb_3+#/ÔqH‘²èÁN;(tØ!ÄYW›ÆiB´«þàB,¢ÄìuD5‡çäêµöLÎZzI6DT˜ÇSŠ Ž Î!¼1 $Hl«#9 ""µ¨;~‚‹=Cöÿ²šõÿã{Ñõ|Æ}5óxŸÕcס†!¬M"Üî»·«|h)FM­î­ve/¡Ÿ4úu˜^ùhé—Ç¢ë>}šö=&ÞGqaÊûÚž`Z©Ä©ŠŒŽîÈTʥȔläÏ$Zv¡B¶å#7Ùu>i¨ð법 8ö§ì »%¼(Àz$<Ó^jÕAè±Dè@Q<æá'‰±ÔÑŠëáåì<½à9ÕÔó{;Þ]{ ¥ÌúC1ÇçÄøÃÛ¬‡†#/0yÎ ZŸ,Ì)ø´­×­-ꢯZ)Òž9­§58¼¹g Ú#9”Éɳ#9 ›&.‡à†"íAI³`¾¸™oa„orLo¡•4ØW afXN™ÇCa NÌ9Øv”©I›b¡¢Ñ®ºèl­‘0&}ãÞ<¾¸„õ‚Ò8Í Å ¹·C—dÆ ˆÆF#7$!±Ñ`Ò‰Ð1GÁ¡Õ +Á‘§§h䚉&;éÐf& "@ ä"Q15¦"Y>ö#9$SZ#9Y§–”Bb»ìª¿5Ì‚8)ÀШRâ¨6Æ4†ÄšÌÌÀiê[F’vÃ%–!•=wI‘žnºÈ’·®¸¥"A ãv7ÈÉW›#9´B1Œ0˜œ&Û¤$j‚(R#/=j¢°˜0mƒYei³¡cˆÆño^Víš™”h6RÛ)©¡”ØÔbÔ’Si±2ÍSM#[)©wc£ȆÌÈÉr&©Ûmhgc …É,p5nA¶Ø¸Ú¶2$ ¨Ô4ãW¿µ×³Ù› ¦™¨ÆÊMȆ¶¦TÚlJPòÞh^ Ð0ÝgaXD˜Ô`ðÙx7•l@À5²¢ŒD$ÇmqéMºëÆ1¶V ø—N\ãZ¦÷i±Ž48!Œhä`kꪵŒ$X¶4ÇƵŽƒZÊ#/ú8ði<÷Tq“hlFèP&ähÓ%—(¼–ÁxbYf¾6UŒfâ–dÞn­‹Q¯UºQDŒu‘9HâG,QH£Ç«%4¨«m‚Ûw–Ê°)¡)*’ªEEË!h0Ì5Y±¾Ëƒ²—=' MÀŒ704Î#70”ºÀ˜2*b‡ÁlNÔ«2¼VAZ@c`1#7<Æ´°d‰3-$¬­z ŠÐQ¬%F³¢")"ÝT‚&0Ý·(C7íËœpˆÔaå!˜ÞC)°l¸a™šœ@ã6¨nìeqå+RÂA[h0˃yíµ±¸ÍYe‹çj<2W͘L*h™Åà¦`,a»ƒÕ`§6òs&ìáíL‡óÉÖ_{<Éí{tñöc¥t{ÐQ¨2¶ß3–Ó!_L‚Ë#9ÞÁ–hƽäCuÆ°xÃiˆ#7VF…Sa¾&—Qê±ñ²¬„Ħæõ’a×9U‹FÍ­Ñ#7f2*²Ë–*P¾ Ytq5‡A3‚â7Â&í¾Ï‡®rÖ¹føø8‘F·PES`~쀃 QìŒ{%8Hovä4ø¶ZÂÆPfP­»s7ä'qùG㧜°ÒÒpRˆ¨+JAƒL äi#7‰R^1¤)J F]è$ Ü@3d60(#9`a0КF$Di#9±¦x&é„U¡1áüì˜#/¹÷ž^ƒå}O£ªƒ'"ÏËSo«ð¦¶Ä±³£TŸ‚`MS¶ü#7êƒÛÕ#7_²" iû§JdF"ÓXßòš^‰“^ÚïÝb‹Õ§ìiFMŸÚÒÌJD?M-'¡Ël0€¨Ë6vÄ$i©ñôò‡“zÈ2ç¯#9Ìž¾)Ã×€ãÞÛM¼50š\)ex;¬‰Ø¶âêž¹/Q…7Rª&i!\ÞàôðÊ¥áR—ƒ#9ž[a.ý·­ÍRÛ÷½ø®aˆDBIaÍL#77´nÞSHBí®x6á&œRWº®±“­Ö¾f¯#7¨°7ˆ‚ÑMiÇ;´‘™¾C…ÑÖ«clXªà¼èpê?½t·ÉáÁ­ü=æ‡ ã§c%uL0¹,ß·†¡ ¢©ï}ðl ÿq à¸TÑ÷ƒw¹}”lzõêiÞ5öù(£/ÉÛž8J!cO„Ù10™=µ…«Äþh<™1êJõŘsb-óœ-Z4*Bt<îo–3Í•#¾8Ôò$â.&üô/Ûöùõ&ôqcg1óZ[†Üb˜«G]­òk#/ÿ8#ë$O“òÛüM°üHwĹà¸ÉKE KHE2pŸ>~ö&Š%E[‰1„ì. ;ˆâšAûÈ(#9@(DêèF>ÌQCHÐ.š‰lA‚|E!*´r6E"m!¡Úè´«#9u#/cå@€–®ñÑbÛ¼ë—M]¶Ü®jvæC—mxµðÍI±´™’R¦Üã»nîÕ‹K (IÊA5(h…Hœ”2B\5­!Ð ¤I€`‡£‡#7ˆX–%'ÏBïÁ‹hXŽ£a‘I}˜§3ß„ÖCº#9©À!V#(2ª$ÄbŽ2« š€#7gÉR‰°!(¯`Ε#˜˜)œ(JÔTY"`›©¢d¢#7¡dCI¬ä»zlp¤ã†Ý,UÒíY]kÙ´VÆ+Ô¦–6È¿'×*ŠT¢¬TÄÆSJ4UAciš*4j*¢ØÚÊZ 4m2ѲT–e4fL“jhʵ6Z@“KH¬†±#9| (L¤Š„;§Ë7T>Îúÿ#³¨;iª•J#/¨ˆ¥ /oÔytßóŸ6÷mâšG/'Cʆ›Ã¹¢dØÊÌÖIµÂ#9Ã_vçœT!¥ß!$¢DSꜘìvÒÔ2R¨|ó[êªÛ…U'Úêê F›ÖuEÓ»³®µÝ¢–¶æ*B£A¹&FJØ”*JŒN3#AM#/ÒšCK8}ú²Ž)Ù¾äÉnðPûL}ß&Eƒˆ)ºp í#„£ Ù0`*€F`í$yB!æ½vDum™I“’¡‰(‡hqî+0Xà˜vŸõÖéP!šEw¹M I#7LCÉaèv‚Ž‹¢.WÆ(côìåõGâðsãºû¥½¹,à¹>£1ûëÌ¢ Ÿ¥ä1›½RKQ£|´ ¹ûI-³1¿ ëË6àã²0¦f3Ÿ}–8ØÆ2»™&š„Ä#Ð~ HÍ’ƒ9S†Ê8„4Ã2[85Ñæ糶ê]§&d™9ÐÝ&ÌþN¹ØÑòðîÓ€ˆ³MªØp#9Ã.é# “c¶6‡È%oì¥C˜âp§vXB€A­æOÀ®’ìl¾n÷ãF„Ц-¥ä•aš1&2'Ì ¸í®FZM3-‡ÎÒËJÄ?9ášÑ¶<'gÚ—0á£ÁÕ-‘ÍX^ļ ÇRɆ‘.ïw½ã¡B _ç'u#9ņ—Я°|$1;m‡Á4‡'~vØ­íw¯Uí@QÚ¦ÉÊËg«Oåå…û³oFÆ)Ù5Mk¹ÝÑ—ÎY•4ô;žEï9a‡È‡à¡ûûô‡0ä)á)öÀ¬H­RÂôñ•%b#9Ÿñ0Q/#7±=p‹ÆhEعBŽˆ·°)X…#9PȈ"Ÿ9ŠÇ´¼ŸäÜ:×.H×Ø÷È¢D#7·ñÓ·!î#æ]gÛ£#7÷ÑFÛìE c+¬˜¶úÖ@R‹LÀ†`¹!è‘$´êš iÉ÷•JÍ¡„Õ±ˆ!½Ä†Å¡´ÈâÐ`hû^Í þ@Ð`—ˆ+°(öÑ#/«1SK ˜ÈÂÝ̬Öb™Ao¨rdˆ‰"dg!Ñ£ ¼ðÛam¢M Ò0A2Œ2§R÷͸m¦ÑL&i-¨ÅÀÅ@ËwK¾j\ÖN#¨LK{Pé·°„MPlÁ Ò®+§ÃHá¨uለÊ.XI¬@®Êž­ªFM$&ADrbñ¤SæÕœnÛâ´- ÄPI{Ç©¡Pß²þ>œïIP½u¼#/áGÇCÒ’èüOË=P©¤³ SŸqÀo•b±ŸFdͺhd7np¾E3i„š1ŒsÀnŽ\¶û:kÏh#7Dï;áç<#/ÒE@|HA•CÖj‰ª¨Š &D0#/B:ÿ-g«M€?Cð‡ohZ¾±oõÓ¦EÉûa°ÿG÷CæÈbˆÆ…чëgéµ?H×¼Ï#Ùþè#9"ó:Mt‹Å®:¸œlˆ,–2sOOŽûŸ†M>:Âœ}î#/3-3ƒõS#9`ÈžBÂ"ðù:΢,ƒв€à­—p¶\¼fI¨³m÷³±õQ41Uëé¬é`¼PÉ™u}ÑM²A@7´B¢Ih^j(ž£[6ά ßÜ“LÏ B½qñQ‡ÚÕ`ŽìŒ1¡1#7j‹ûx#7'óìfÈ’£k}#9("ìŠUCÐ¥b)Tˆ,+»æôí°±É1x§âè74#/Ú_Ô Ô…wx¹ðòéì¾/_×ë„¿¢rI r³Ÿ÷èšÔáœp½ËZHSXõ7¾gm+KõùŸØ@ùìkC˾`ïˆ*‡\Õ](Uݶ[«»«Å0`ªÖÂlû7Ü21% —% g½ãÓùêùq/ ìñŒq@$7-DÀØÀ˜Í}!§B=Çíê¿Ò,›pmkAf³4I…0êÊ’ë»Åä*%(ËÊæE-,‰dDl%J•¢ñmu–¤ÑbŠMŒ7#7ˆÂ\Û•Ënnãºo7—n:ë¨Ìs¦.Wwn‘W/ñäÛ¦Ëy<ͺ¹u\Öe‹Ýà*”1ZÅ0œÂiµJXÚëæÅt,›I¶ñݧ-wft×$jT»·AʺËe£hÑrÚ‹] ®A@˜@ ‡øôét@‹Úà#9iE>XööÂ{!ìDGÕÛðïS7•>õiÑàÄêö¶6…ˆ„ÀQ=l)¤tJ¢÷þ*žô@{‡Ëˆ€¿÷]÷Ј>—™<A؈;¢‡¶P…„Í1ù2b?0à?U^ºhà„ùñ {øú‰ôà¡û~®ôþXyÁ;Aô!¥Dÿh…^áÚ5™‚*Ôffm—Ë}J$JHBœ9m‚†J#/ú¡QjpPµ£#7ïû…8¤@eCKÓôx脪#9”„T5Iµ‹ke*Ô)heÆÁ Ù">³ì`^„ÂHR†%ÌwhÆMsn‘wvÔçw]NêL-˜®‰MA¢ ½ZsA±¦Ïx27¹’ɬ\KJx~?9¤Ø”ÞQÈp‚Ö È’bž•Ò“$ÍÄoul´Á.õ(F’(ðB0%NH…ô¦:6H‰#95ézU­æF£*8b8¤¼³¬.À\Â\”q˜"”H 87õ_ÅܼDàèi~H@¯3éòŠüÞ'ÜŒÞ ¦-&"D13+)„n}g÷?uÌúspæp…䌽Ê*ß ´²(É$³JTÖÙR›iµMµ•,$w(ùvð¸ä‚t7Gˆ%X0Å–’Rbd@¤¥<úWà|LrÐR{·ôˆxqÅ bɉH‰  ›©«JÔf´6f¶Í’‚ƒ~ÔOô$<¸uz¡å‡L^¢<ƒN¡OÍ(ô“¯êLùÏ``á$›@ QÏÛ›°@XšC"ò¹ÎïÑe§œ|@'äŒá!>âh )þe•1XðÚ¿³Î*›–VÉXº5s—ˆ‚¨" EL.Ý®RÖqÄ#7 T„û­K£HÓAÑò1´)"’ƒq8xÛ­púšé´ºD?ô ñ#/÷!àGÄòf½<À-%IgŽ0Xà?Å¡)`Ù*œ%h¤ƒÈÌÄ°Œ\p#a,¡•rEÓ‘È\()O>šz2LŠâ‘7$PÜòM+=÷Ñ/hqO<îæà”Ñó™H¢&×8}?šÞë š6º¡«,´‰4…&ÔºN3öCA¯Œ«æaµÇäê§AÆ/œg×¥½kK®`Ö¦»Ç‹³mä%“$ÇI#L+¬ÇƒQãS1¶ìŠ•ÐŒ¿ÓbÿŸÛ4´U¡£¿>MS9»7±©´3p––m.h¨[¥ÙƒW/ÄíäžÂrHè j{¸L§#cÐ?d ¶JH£`'è‡LI=ÖH—ðæªT{»õU;¨ŸÛ( !F ¥ó`ã#9«?=”‚4“íÈQò2ý§°$Оl7‘ï0oRÃœþ7½kD¤<“°ózçëÿí2tå×ÒüýŸÀ?Þ•©ëH#/AуHX*f>εöšÛ'k§Ó(<@æ?sü¤(@ýß|ðöxú(¾ëÓÍ»,1÷ö·NWJ”ýJˆª6Oví5ûè‚S]¸ððˆµDR>ðyª(MHH@ÎP6#9½c€e¤4J‚*;‹lP‹CuÀívýŽÓ…Ãx\¢3]ÏCuÞMû1rËUé#7Y½œÄ8óæUŽ³9m˜ÍR‹wfÅÍ3`ãâÂbÅh¦qw–l ©ðh)3>ˆá‰-1#/à*5ʆƊÙgã¨OçÊ{!ì ¡|ç]ÌÌ/VÇ{öþé30ä• G#/ÕlãV`|ïÈ„ömµ,‘nTÒNFëyƒ Ë8(æup{Ý›ã{B’–±½¨!Ì-Mƒç$ÃÃîÌì’8Xî¬Ê*„K«*%ø«‚P£ï‡kzþQóLPßp‹,Ú¶á+hBÞãœcCÔ»}Gö÷gLiËÜh$&IæN– ©6‚4údVBG.©FÈñ¶ë Æ2ÛCÉÔÁ˜ÃPÄô°ˆÑ›ÄciiDšMc¦—cè‡vC"Å9¤S>©}ª·K!£QãY˜#9„ ŒCmÖ6ˆË`3ZS¹Yå§k:SÍ/_äõ¤ó``òv¿-ܼó`k×_b`GÄ|0}¡¿âA³ÜöÉÂY^ÖéŠãǦ½ÛØS”#7@Ó5ÛˆãÏ´®Ä'Ûʱ„ã¦ï/*/áö#9$S5¾Z‚ÀQ ÒêÖD–¦ñ!»o¯ð¯Á°•'D dzì‰v3„6z\'ð˜³×û4©Æ[_º®š‡o¼N³èõŽHŽÃ6 cG±Í­šCH\6‡Â' R »î¡¾ö²ÄÀ¡™¸vËâ;f6Ѳ³° ®íˆI‘Å#9ÍëFPUt=â>J;æ/i0UhMrÐ$ÔÇ$=åö{}ùà<Æ —÷#/F–/SK² *ÐÃê'ÛPz§ [=4ÒÕ>ROD½ä{ΉÉ²Ž8˜„.ºâ¼žkk×dBafB4>Û?Ûñà£{hLÂÐG†8 „÷z÷„) @‹²DaØà]B>Ï»ÜØ5ÉÈ«iÉÂðwFG… ”?óQñªÿkàüShl¤pQÜÀý­kÛ8’[!dšÌßñ˜µk·çêåGƾÃÒe¶÷{(Õèr¤"M¶Ñ  Ä±¡°Æ‚»_·ƒ1­Ô[er¸înðøÎõÆÌn¿sôÕ$æg¶ß†ns1Ù0‰o4ô¯¨5³Û7׎8“FyV.…e²XÿaØbRCiDˆö+íHûôß\} ¿Ð+Áî!EJ ¤ZIRƒ·´Öl#/q!2}};t)g•zÙ_á#7êo@ C©äÈèëÍûƒí% åŸÐúCÍÁ#/>óàs‰¸_Pö?Yä‹#9¦lgËrû#/„“ò<»ä™ãß ÙæïÄ#7— T8‡îp < DA¥‘FP#/'lPvµm[³˜–÷8í\äQ¯ºÚ¹`DUÀÖƒ"“ÎJx Ú«òRD`¡µ ;èTUI¾?²¾î ]½ÇS v`#/êÄ QË`¿#/#&ôpêr%:3ɱf4~®ãÑï;´­BNÊíBqƒED§1ûï:®QS„J)&,P¡(HI“AI)€qwò6t¸x[ë!=Û¦; 5Ø$:‡ï@Óâ³;BØ’«B#/Æ1XH áq‹Zñçû_ÏîfVREì«ë)¤ HÚüG>»º´Õ}Ž =bü|;üÁ´!!@°])!Bœ‡Ìß|Zw¾¼Ù€oè„÷‡wø ò‡(Þl-²©¡Å_ºývdÎ1›«2”)ŸŽõ³žÍ©ðCqúìc_PŸð›ãm„Jœ€Õ¨‰Ã/U“Öɉˆí{ˆvþ»då\~ºÛæj9 =¥ÄHéxøÝÿWöç¾ø|#/”ŸêøÞž'9+\YhRB¼!ÇÇ8¨üQò/Í‹‡®•„œUA¤_‚l<4 ÀÊ4ÅàV1pãUuŸ%zLiIâbæ nº)ýÿÃ3±cÇ’:öò ÐS÷pä“ü<}û}_Û °±"1ýé‹1ä#/ui.–%õêï#7´]<Ôöqë,zoXʪqЄÄ:oÁ#/¼SÝTn¾~·Œ[5#/óóô-E‘äv\°¡I­Â„“WÙUñ[‡ »âoc,Ò: ƒKÙ¦nAàMÁŒ Ÿ³ËHñ6Tê—#/ìÞ§ÍÀçæ]dý{PCAdƒÔî4[òTÆÚÖÔLû[„êË\³äë¦i&3îäS2M£ (–‰ +Žz·ëÐxúDrø’C$!ÖÑ6XWÒCHk¦ª‚1³õeÑ$®°Îu %‰B!í…Ã:Ô&¯šIî=û~îò¼¸ Y€ŽIh²bÈ2C0¶L@bÖ¦Ù¬•¥•M¥@!H„“ëîíÐWÇ9¥H÷!êàù/%——´6wø¾ãÖ6°Á çˆpÇ5+@PÒ‡Û÷ö;mÛñj´ÅUD¡™FT‘fÍ›DÄÔE&!&4eˆÒ•#&ÄФȰ-AQÍB~Uìë{÷ê‚ž{ñ@Ý’ÅYÐO“'Ùšœ;èáñ×>Ùyp`ã7œãÇp¸Tèf.SaÂ!Lj#8XÔ¶cÈÄÈÃ1H‡æHL/Çv‰jãò?qŽŽ¥0Ž¼iæÿ‡N¢V÷Þ|ØT}œS†¼Z­èá‹áe®=U±û»±|ruMcÈÚé"0= Lm·†q3Òá~XlµÓIª©ÈCæêìÝí>TO ötÌW7®ØžŒÅÜZú°&þ0ý;å—#7@šøJSÏ;ä~߇v*ªO õLžD Dû?õ’›óS—)T•´Úä“”Íð°5Æ©$?D"É–ƒû'|!Ùíñ T¤Óå HÌýh hµ–Īdf©›%ÉÀ¤¥¶¡§DµÑ ¥#/P¦èÍøîªm¶f×.¢ÕË;­Èf¹j»]Ҍnj†ÍÍfŠÌUÆ@2†ŒÚlT¨™C¼B¤Â j˜R+ 2#/i#$¨`aŒHž#7 LÅ™ ëhÛ¨KR¬‘$Fô÷¥Tfi-¨Õ’Úfׅʨ Œ#!³$ M¹Yè~ü\è´»3(iˆ¾çP)„@ŠÒå¤p0œ¶º†Òáã[w²FäVxȪx0ǘ2aŠBh¹‹M­L+ö¿pËÔáS FVdÚc8tÖD3 pPQȆyÎODj¤³ä:ãk‚ÄMè¥qFFSV®*Š@ܤxšÚF“iäU‚õ5³fŠ‹gÄ,h+H€ÈÒ1¡¤#/î›z¬Ç¤^qØ’xï6ÝÍ”]vÞ1/SÉ"$:yí¨ÓÊTT’iB A?yy)¦…Q EA4m‚,³Ávfµ­2ÓˆpŒfÙ¦†‚j#9>$ó‘®#7^’·Ï¡†ÕG*16m\œ„_K­7¸–08}09RÚ‡?^Íw#ZŽ#/M¢.cP,Ð1òƧ†2¸Ow¢L:œšÆ((­–ÁLˆšc<¤âÅÒå‡]Ähi¸&œTÅ]Ì1"¡˜èlhÜÄÁ#Ih6(@ ŒK˜ `…#9@è…Ù\SDc¬­ˆBS€Ãƒ¶«NÄ)HpPw\pý)Í$LGõv‡›½¢3(ɤÍY–Tæc¨¿‹Y£ 5FM®õÕÒ߇×ÕÈîÉ’³™Äzˆ0„S#9ªÒT!,¤ÉD11 ôþÑ¢…¥#7”Cõ©LSùTÝ{þ3~#9‡ n‚ðå†Þïáîò' Dd\‘¡`üp€û µ#/6ôÝGñ—tÌ7ãN#7Zq}pçå¬Î&ÂöñT¢D#9 Jƒ$ÊÂGµ%#7t嶇ÏR}bdà{sãdxmLJףªYPRÕ±†#Kö%öIÞLvïv”Ipq˜×všH=¸ ŽÂ²A©?¸Å—¹–.îˆÑZêím½µåÐjÌÆ4#9G‹˜h’8Pm£jGkPæRã`÷4H¢å¦Â4À|÷©eÂX@­MÍwf,Ù(eï”)SD#7u’¿¸ã5&ýîâê„Ä‹#7€ô™‘‹cìï%p—9ÑöÙ®¼·*Üì tR`6ø¼ævRc’p‘dY³ÈÕÇ~Ñ ý-vbŦ/Šµ‘³–ÙÆÌa2àÞvO¦þÍ¡_0„8ß"|ä‡èk !u@£îóפ<Ñ@w‡Yøœz*æZü2VJlŠõ=¼ôäœåþxå: §?Ý#/— Np¦QÀþ^=gµ÷î,•KïÀ²ñtM0†U‘(ƒ­}ߌSå=‘û~¿·èŸQ}æŒgt]};?À¸aÀõZEü=ŸtùÎ1 ‡¡²¯¯‡²qÃåp˜Úfib›ÆýpP¢ý%Xý{ë'³ã´uà¥åâò_¦o<1!ñLDfü¾07Tò¨rEL„ !^¿Ê€hìð‡±L@Ï4&NË ÂOZkš±Vdé …äóÓ—Oi€w¤Ls‰9Öü'#9Ó•J€³·ò,'·{1éÇ]" BáÔ°xaâqcCÊ×} Kàb”TYûö¯®µb8UœFÉ|Ò-sù™V…Í#êoN#7‰3 Ãv%i‚áêHÃ#9×hŸ£Yäoƒs¤NGX&l6 H²E’qÛoù àWdlk¼BƒaY£1r”ÿ>ƒPЛ–JÒ1 Ðï"ãD¹˜#/Õ)’²Ø±Êånš¬mt­Ö6æÒ[\¶Kræ«rÓ»Ù®EF¬›FÑŒQQ\¼ZÌF„?„—Q´›ÁÔñ<m¶ƒ¿\Fl¦fü©0ŽYžÙí4ˬ‡Ñþ¡ñ8¶•àK£Ž#²”„Û*‚áÐùåUÓ¾ó'äà”8bnÃÝëîïÌñúÿO'â:âø½™„€}òùÕ_¤ óˆ‡Ä#/?˜•)Ñ~ªÿd’ÑùÝ^@ÁCIÍ"€U`»]–šS#9FAÆHO>´4¾ˆMfVQ–9éfÀ^ÓpÏ·VÂ2³#9žäÄÐh‚nÀ(СH 1"jU0‰j„€"OOpÔ›;*¼DÙØCgÈÉ|$•ôC´²%²F‹UImd¶+ «ÚI•VR͵ ”(ÿt÷Ÿr&‚ä¢<ÂA?ê Hû$zuý² ú¤}õÕŸó5À*?ÌMB¤r¾ /®0aÌÅ·s#]¾láGkY õx€ú BTÅñU@z"ûx6ÿ¤ö¯õ#/% C$‰ *»æ;«®/g='£‰Ÿ~Py`ù“ q`>hPì‘h(F$‚#/á&?"¥Õkö4³TÌÙ$”¡ƒc–HËF“bÍ#7©(ÚŠ”¤É)%bš©¢…#9Ah)T! I!) „”¤…¥"@$uò¬ú+®Fä‚ c`ëY“0¨#ã­+‘"=Ãc6›M°*Ï.œéÔνNMé¯3׎ºª±`\j<¢ˆJˆ•I]M3 V:BLbm8Æ2" %d%U„ˆ(UƒÑ¼†û‰!„ŒÌá(Ø8#9H†B"*¹é7R0Û‚ŠR"ä3 ø¶Dwöbš˜ PÆ`Ì$™˜–c4eX…òÁƒ´8f2.¤ #/•dˆ]ã’š„g00õߤPÚÈ-Ñ_nŽÓpˆfíÓø/UIêËæòuú={û3†ŸO#9(Ì2¯>‘š”HøgoódÊ´YñNëð\(#9aM¶~§W_«­Ë–-õ‹Ë[4ª‘C:=Ê%ˆ`Fá~bTB!ªp~8©‹„J± z&Rd"Ê)4N¤r žfµ`ä;‹ßú·t})àž¥=€>}XТw5Ó×ÞnÝ5ÚMå—R¥30ö•Þ«W5ª6­j)r-\]uê·›y"y'ºfZ$Ð}¥>AŸá‹“×Ê÷"„(ÅLb©žIüzë¦7fÉD)(û¿f÷­æȼ ð—2ƒîP­Â[FîI…k£õ £öï1½¿#7#9Ö“6–iÖ*;gðŠëúTk¼\Ô _Œ› ,h½ÏùVZó“J7Šé“©ay{ÖŃ@1LŒd­[ƒ:wï´6W"jÎýsW¾.D:ÙÇix‡‡â2.Ï|&Ž-Á¹Bg‰srªqŒ>ŽŸîÒÎÇ®ÝC=J ob"A€; æ‚X–다£0É}1„ͯ2õ.äòŽTO—³ŒFÉ°×2©à.*âw[Û=ö •:Î0ÜÕé€tW¬Í4¢Øñƒ§Ÿ=ðÌÙ`ëÁò5†Ûݱ“F1x1l×È©èÙÇ\í®™ ´á¼»ž£=µ\Ê­Jæ8xÑsÃù*è`f‚pÑÁÕŠv–P4’8œ9vÒžÛ=²è5³ò™B÷û⺹á;¶in‰âwÆÍ"Tyß‚ãÐi1ŽÁŸ,×[é$žÄ§KU=|_Z¼5'¦ä)$$ÇŽ{ËpÙg9À£d‘9PouÍ„ýͪëÞ!s.µ#í{J:˜3}wÌ¡’A ÷HozJŠ7ãÂKp¿$ —/P…çÇßÔ¦®v÷Ïs§1…ߣôT«9c¥ã–H0Õu(ûXj~ví¤‘ˆ‰!A#9p(!Ûmˆ¸jå¼SvD–±àbJ—…´àÚG뎰øÆe™[³Ë·Ró• Âæå÷qÃ-žÑ0Ë÷õíÓ¦q»¤„Rj>iØ4Ó×2Sèv½°p:mÞYÁ¼ÌŒ †c{ÙoÞsÁâ³Ä¹´kjÉñN#9î/¤ÐR9Æû[ÃF-šÆL$ƒ¢fb3¶üH×ŵáé­öDä}½þ»1Bdk˜’ÍgG jU'·4`F³Vª±*©/€O™æw*«70µœ»@“׆øQAÐ"Ç#7i‰¦r0“¸ƒɵ3Äèl³Øßs|lÙÅ–®T›f0ªv©± ŠÑÄâV\³C',ê½\ ]xàH ÉãNR™¾‡}¸¶Ekj‹Zˆ§fÞÞ3¯ ‹ XJGu´IÙ³¸Ç:Øm¼Ga¶RÒÂbP#/‡i&½ftæ§cO†Ðò´á!± wæN¬†ðI À2v¸Á· õ£¦ÐtÄ„o+œ°Ù¤’S";ÓK€ê×WæÈ~Ù.r#7PÐt‡ºž<”o–|­ˆO—vØØbÉ"êÅ,ž|¶´¤ :woÞ%¶‹ÍÃõwÞáy(©âX” Óf„·Ó¥Y­D“#›á÷—1n`C‰Ó4.8zØ{†R±¯«µ‘OEˆ¢;2Ѻ?«X×~¼µvnƒ V½{zbnùqš¸Û~iÇBZLõXñsÁÖc]»Ë..éuÛ¶™º+sƒ4à]x¹n<Žd`%RÀ©¼WË>;Äh…ÉpÕq€T£—%VíÎ&5Sx»šâ¼%ÒÞ3—Ͷ ˜‡ñ/Áç^4l.î¸ywê§ÉÃh3q xÈï[x97”╬J#/Á‚±RÌÕÑz ‰û‘}82¹!`ÂõNðíV¨WädE4{ô|Oo¶SB‘)Ò$-05bZhXÁUõšé´ôqv‚¨‡B–ôŒ«m…ꌳ¡ãžR†«Ñdn/Y 6wŒàN,Eƒ—$Ì*X+¶Ôܲ².pR¬ðný#7G8?3¶¼+¢ŽÑß³… Èø&jB­9GÛ¼gûØr;Ó\ïäz9@ó;ö .OA›r„;M!ŒçETÃñ=#x¸;„"\'žj›«o 7Ê ˜<†~évÜ#/W£\F3ŒÕj<Æ=;–ʧ˜²®ñP¨jmÉGRÚ{8™Òr,÷Ò­&ÛžA]F 1C‚¤x£jx:¦‚‹KÀ#9+8‰!]`§ˆŒÅ’r¨öF®‡EwÄïÃÀêh#7˜;‚d`“ÂX#7Wû05€nb@>#kZ®·&@’d@‰r ¯`#/5 Yé¾<å%ÜoVffE.)ó-äB hAvc~&Ïè÷rf÷ãø•†úȼô#7#9#73¨ôê!tÛV9RÚ!X"ŠuhdF±ôøJ#7¡ï{#¶}ŽžDÑ ˆ,0ž<~ô“м°5ð>Цm$RªI*«ôfâ9èW8LMÅ2 _Ò#/ô†´‘<Þ/ž bhøIÁâv‡•±ÝÕúœç™‘±6kïœ+¯®ß\—• lF"BÌ=»Æf·X8E²zÔûìÑ›N£¶”fV’´l¶%͆5B8Ð7 %O1¡c#xÔ˜µx«ÆòNíȵ‹Åק$É#7J©©C C×o#©#/‰FTv(ÈÉÂ#7³XB™”‹"(ÚŽ^à´Úk@ÔX¨™APcJ*"‰…EK’¤Œ¤;B]I×^ìÆÚûΉ8Ë"£S#/98ÛÛ¸Îø6Ukƒ^F|íD¥DS=Ï"š~Y…&ÐjCPdK@2¨§Â¥ Q2TJU#/Úr#/ÜÑFµ|U™lðùôtÜÿÉÊÒÖ¹>øf¾Ë¬xå²ÔÊ#9RñÌUŒc–(Vê É®_;Q Áîa¶¶Ûy•ÌÃ7Z1Ò tlÅ¢Ev`ÊâdŒÒ©>,ÞAFΙ§1#9³ÄðÖ:¸ªQ#9]xZòh%Š3RC1WA”‡ ¥PDiòãOR;Æ]ÓxÖa%‚ŠvºƒY"³aff‘5³(¢#9ÓZ`²2™-,jH¥„»¨¬lM4Ç„$ä±¢·ƒ–Š‰OéyŒêœ¸øÜ<#mŽw4Þ¹m5+‰Z3x#¢Ù7T€±bF4¸HÔxb1Û¹pb™©[Œ,MÀ(Çcuìeé©M2´u㬳{‘šš(ÓD$5k›ZÖ©nË$ëa­Xõ:âç5l­ðÉ‚6Ć61BkŠ‚ãšÕBÀEšfU‹‚™0ÄÛPjÍ+m†I%¯Ë|kSžrvmØÄ ‚ÒŒceëVðØ©#7PPˆÁ {«Q*Aj$ÇcLhÇ»*ë¡¡ŒxÉl@² (ÑdmÖBæ¤KÀmeS\Êùf•“%+XIw­Ü&]JŠû ŽR‰bÕ7·lUñ¢·°ã…˜æ%"`œNÂ6ÍXk¾i§<]u@1r&©Hí›iF¶0E¡àgúy€÷®šzÒljq^Ts–¥ÕkHÐÓ8:!’±Æ£P‹hÜ2”‚¥#9°È4n%48´†“M¦&¡qqhÛÍÅ·“%•Fë·§; ÚØM˧΂Ö¡²*TVº¼Äs¸Šµ²UÊÑ"Œ0Ê5C7cWmÝF?'Æj¤èB) lSIÿæ9--¶Cáµ+#JB#9š#©ªŸ–FÙb„$¼*6aáF”ȦšHHÓÉ„J‹Ó‚nÐÛô}9È5Zœ„:ä‘ÌXÜ(Ê(-‹-´C!†Øa)2,™É[ ÆrU<ôLÎ-ª#9fæ`éÞQ¬UŽÔÁ®% JpÎZ‘JkLM0 „m’I» &9¢#9+oîíOß½{AXGÒ¼ÃFPGÐP(ÄXģ܋F:Ý”pf ®{Ábiõb7°'–S§m6`ŸƒØùÕ⇑[+à71m»:k])*íSH” ¨TdƒJˆaˆ(Ò2#/„ˆI~7 =ÿß‚œ'Ä#âHü_ÉÙžÌú}y¶ßo‰úŠ’†Š#9SI6ÃS*Û#91´2c˜Å‘5¤¡j™V(RضJ‚­b’Š¢JÉF…l¨Ø£Í¡M6I¥&ÉJ6R’TF†4´Eˆ”‰hÉ#9f‹)¤R©£ I0Û 6a”¢"bJ¢©E?[áê=œü'ô|Gž7! å¹ö‡‰÷Iæbiò9ÀÜ“îIF|îwô½íÓ¸ýWÎß“¨½œ¸À~Ï0+øÏ+ÆO¢ÉPOC¬ÅóS˜%±2ÿ0ò‡Ô@ο#7tÛ¦v®Ï~ŒH;£uuˆ¨m°5¢ãÌ#/š€å„Ÿi)Ñç0!®¢ 6ØT-ví*1v#7¡3% ¤i%ŸÙZ“'ËrL>OË'ì‹×ׇyoCCü³Q¡ðª ±BJ*¹vöð5âS=§ŸOQ&&Ó#/MŠ7{{ƒ–TÄ!àp»ò?†¤ŸŽþG9ßêbªeT‡zȼSü5kñ9Â,ÂiñœT„=+ü€};Vúkh­E&Õ&ÑjÄZ’Û}Š­rÚTjP¤ÔhŬF}+µs6²Á13úO¦_¬ÝAǃó‡8m.òdQ &#˜©>ÿvíhßMH<™¿‰q6õÀcXb#ÈT#Pï¸iÓâŸ~®ÍV4Cââêñ¨ºÔQÁ’±MI¤ÄEÛ0rDØ0mǦ”Ô\±#7A¼ê@¤NͶ`к‡e„5¿¦Ma<#Fc…DF6I¾±¼ÍRšìßt×ÂW¢“z\ÑŒLbŒ¿<o[¢Žl¸<1„·wy†PÄŠÒP£‚&FTº¤“¾p<è妚O#ãA¨Ò}N)H}lK»Cv,¢9j±2#/—Ž$J3V6ùÝ‘I˜šæ×7É85öàr[>Ù±âýYÍÈÅ4æ6‹,w|Žº8º!á#9xÛ´L[D{àà>Bn‡{²´ Ðß3#9xI¬ÂŠ‡O#/0é‚K»À¶#/ð<6ù¤ª©à çeT6ù»ó¶·Å9rMÂqLïâì)«à±H­Bû{4³fþ»â½ùÅ/R=ˆ*ƒø$s>í>3~´É>;Må›h|‰"h×êßoϸ¹›%îê·A}¾³Û#/ rr‡=A7¢ÌÁçÛ± Øg‘ÊIOq”.VF“pŒ3ʤ—u¸†»æqMýÇ#9¾Ù#/û:s+‰¨É5 {]Š›ìbyþ—Ã1Yøöß‹•EðÖÍL•TR¥›k×P¾óÆé §¬ùKÛN”À@–dŒ Ü':×€ZSø妪𠇈̵Šú}\‰fÓüÉ"º×w,úRu8V…„!ÕCˆEŠŠ¬ãôQÉ8Q10QÂrÂve° ±Ò‰EÚœˆKŽ€#F ¢cÐ2`(Piâ6$8È'»Óþpð‡…àhãð>Ê„(¯ š<ºO`¢À$Y=Æ'ŽüL“Ž{;GÛ}þµØù}ëÒN!!Ä ¶„üŽ˜ sùÈYdö•Q*…Než]{â9¿é/ñ¬£gÈ°äyÞ~³yíÀGÄ‚ØǸ†4Ëê?6fcÆï#œjǦ#AÈ唂n"дÿ„ÄœòFlf/ÃÇô¡b>æ Ú/£‰A~?å)RP¬D•Q¹¿ÐÝƹñˆz…Šù¿Ã‹[0pm´ö¼%0±íöü•¶ÕuŠ„3d÷¨'åñtŠÆæ³#/K®š,0!’c­ÙS]ߊ#/ó<Ùâæ¾ÆNÓPa=[§´úèsíõðX¤s{#9*ËQü¢Ÿdôýø?ÏÀ[ùîßÓZhÉNcD¢®ÒãÏ)Jñ¬Í)„ 9¢^7'Q®&¤|n=Â3—Ñ”È75#8yx|Ô®ÂI¸tܤ±%¿õ?ìW–¡«dïËèX£‚GSÈ“K’ñOPNÕ>ªt³Žu3Êv·::u0QÝ#7æé¥#7,¨71•Hë²í¶2X8 ‰¼ë´ã§R:˜/útÁTºœ#9õÔI£ž§UrîJÞÌo!†nYUhm2–L£J#/D¦vž0rŽ'ndî Bö­¼¼í›ÑH88$µ–B ƒm¡§zža†ÀŒä£y¡03Ú!¸@­£(qP#7ÃîãQ§çRIqîàì2wvèÒ¥ñ;oMBZ@õ99b\ȘœuZž†ìæÈÔ'm&&w ¤‰P2Ë»`é¡pãÙòFxq#725Tñʼn©ÌõŸ¤Ü6)#7”Œ–c|é£ N§LnfP&ÙÄÀ«H¬MˆÊGמxápsÀrf’‰ Ö¨Ñ˜XÛLîÖîRä„Ëd¤…NáHÝ.wKÇÄÜå¶,@E Í#/ük%w©ã&Ù§M8ˆÜ+Ba‡CËxaîbκÞã cfJm1{Aƒ(ŠõŸ?(3¶3¾ëp~wëƒ$^ŽÒ3ôÍöhÉ´nøƒ.å2"ØÖà,«­@¦`–’*&P'Ê£/+ºæ¶ßYý?ö‰Ùqž"[:æê©Ýºç’¥38ºä|e‡—ž¶ß¨ôfVIñîÆü’ÁÈM¸.Ñ]pݚؔ¬¨Ã0¯‚æh7áÂ#9ÅàÁr¹§h£ˆQˆj0‡4ï‹žo¬ ÐK@dpcitÎ ¥*q N]qG„'Ì#7Qo4T0DS)ˆ!!1RMj%©,Ü)ÄEµ†"rŠÂµŠ·š;b ¢`î5¦ãÁš„ÉÖì± ‰ö¹VÄÒ<Š–2 cj¦"tÀTœ4XãDaó‘É#9q׫ÚÁ•X±Æ¬Œ1•eÎ ¬ª#Yg˜™LÂ}á³Ng!d0„AÉ–º’“´… ™'Va´gV%´ð*ˆ'*oMšë†õÄF¢í3m&X ݶÛi`¦.G©"„žj`Ãó¬`±F¥¥%—Öí,•FŒÓ™Á ü¶À`Ú]öYš\“Ã#cÆò‹ÚCI¥=ðãC6@Oo]6.[d¤ìÙɈm¶*é¥Ü¡‘Šg0Ú›LêiÔâ “;Kܺ{Õ—[9ˆ[m0Zyk.eŠF«—Vë½Y0ÈI±Ýß6&|ËáÓ¸„æãÌÃEñ]fÅÂÉ]¢¶·…¾*XªwŒˆylÅ“-.æÊrë‹„ Vs™V¹›ÀtrYÌÃ:JRhÀÂ牉©Û>PÒŒ!Zô‰S7ĵ #9º8òèyÄÒ黆ºnéõÅˬEÌ›¤šDô&¥Á‡~“© Ð9„5eâœ|¹|ªUš­‹²Ö3#¨j :g:„ 2%§@l7 kᚨ‡"ß‘kkÌ›%ÌF™®b;îÐÍRX#¢ìî\üW\åì"5=Hé4#9Íf(Q´pÌHÛ¦lšÈÐÛ™éÀé­^]04©v\ζ–€sŽ°î`äXë@u½¡ºwËȵ"¡·BŒ5ÞÓ!>ç‡Äj4l\ð ¼L–³¦lŠ*ÙÀ#7!äÂfêÂݘCƒq£H±:Æ43±yP‘LPAŒUKËd39O48x†D̨*†Á#7LN;³;!΄Šóy¶Ý“œsŠÈû—A×qÇaàÊÜÏ9 11¶HŠÃOeÀ×j™£3XýÝßc\a9³Ï7–ë\öÖL^ C³J©a°C#%Ô÷ÀØåÓ$ÅÚæ[A h¸ÐÅùpwѶ7\¶\ê.ænÑ~Ãð„eí²æ\M‡\Ññט>ï-Ž]sæñ$ $9MŽîx/mä:þO—Xx맑-ôãÄAYôÔ–›PúbSÞ²‰—léä–y[,§qéÙ:˲^‚0¥Þ_–Ë IŠdÕ³†m£y²ÄÈèlk."ʸL\2o‡H<¸kä33°lÒüÔš´œL€tÂÉ“Ó-±QðÕÀ™å1ÌÇLŽ@àTºÁÕ¬w4q#q°#7•Õ3Ù¬šOtaQS‡`pØêÉ]:óß%˜’‰1z–Ë·U*Ói"qãc’—kPÍ dgŽ$4Ë8'3Sð˜pd€¡$ÌSÂ*‹± hQ‹LF»÷ß'#7x‘]¹ÐÉd4·=˜LMµM4+oLC[|*d#9¹‚^ ÊÙÅ»©·™¨C§‹Úݘ>Œ&‰MNNpŽž,Ï Œ{‹Â9U8L™ûs=Ÿ¶ø 2Ñ2Ú–vA=3±8LÉ$é†wqèÉWjîݒ➤ì]æ¤*Å5iÊí3"¼¶Òýœ¸/“SQI™’æµÛi¾\Í&>2Ú(‘â['s¸÷{÷1æ¥0Ð<Ðq#“°Æ‘z°)Ç7„LC·b0gaÄ‘SZü$Žd‘A¶¢„H÷°Ì‘Á Q†’®*”5Md×À#98î† òuº%=ìÑ5M@ÎÚÀ£x4*ùð’É Ã'WˆwF™ânuî.‰G”`èpƒ‘\Û20Ž>suá ²IÀtN‚x!0¼ä¼“L<^‡#/祌V1#7„-ŠSWHiº ¬ÅY.“©Ð9HE±»¼ÕDg#/%ÑfN%([vÞ&ãaeHC!2 J¸F+.8i:ÚБÕW® Œˆ6"¨&šìƒdGfAò3bà‹‘TìlÌi4ÞÈ‚‰‚è”7ÛÁVFHF¬-"«–Û94 ³‘v Äa‚êM:šDî©eZ«¢È¡‡#užd˭—eu&$ÂÐÎ0m Ä )¢*;ÂóÇNî<¸› # 1å5ØN0‡YŒ1C™Ø"ášQ(Á4d0†4¡#7t¯^õ~IQQ²VKo±KCËχ@ùö6±ÑªQEDJ•@1¯M^;B ¼9mïñ_‘,4ÓO¡@0$ÇÈ: ¬I®¤ê ¨@OPýœ>qÉVz#/ˆ8#.u{r(\@ÔCk2‚½QèÈ“j,Îù0ù›álJ7#9Ô™0K4£Xré̲ö7–Ç…D[D¤Å4s#ºèTœ[k®Ï½´ázaº–ˆQ#7O.Ò0#7¸[³I¾Lè àsû“N}¾¯: =3bÃ1ùu„¿²킃Œ›< Lùñ ¾»ê;û߬û”óžm:,4­NìoÆ3ÒÑ Â?­€r¸ôšw_.#/y‚Q>•C”ó°³1ZóƃX0ņE˜ØN1#9sò;]™›F¨Lâ]dm°Á¬O0••‹"¶•5w­"]ç<]Ûo,Ì‚cŒ—§z:îµÝzî–ówhFõ+†Âän0á …”´¥¶ÛHFešÙÀÙTv1tBPè0‡ Ó!2‹ƒ»ŠÀaÈý8œU`=ÐΞ©Là½%8*+Zð¼aj¨š´.ÙÍç<öp*šf™xF‹b‰s¡@ÙÁÂ@ÖC5BÀ>á(%hDêü<¼ßIõú½Áù.¾ÆµÆ÷çÓµû€_7–8ë#7Ÿ+Lgä¾QëpŒ¥ŠÈt6-Ê5Vš"t@lÈ4:HñÓ0´±\hh¬Jì‘1 ”¼4ðÞ‚¡¬BD˜Nã ߟˆˆgáç  žcù¡NÖx£Ý¨Œ›Úú¹NNg²ƒ½«9öCFŽª‰£*©ëSUyæBþ÷øÈp#7=|=dР~!CÚNk±F nË *q^RjqÆš‘ÝÙrõ'ÏF£UÂSL†FöóíwµáOºqÝyv2󷓘z4Hx":Å㊨}_0ãçüýydöIÊ#9!éAÈôìv#/ì:ò€Îê$äØÃCD~¥™?+&PâMøã £Ÿ¤ÚA”-kméŒlȳq…©g>;è¦Ã0aÍ¥g§80Û%‹#ˆ‰8%Q¬á†tÈkÈÒŒ™Ò»}@}°aï°‚¾™L%ˆ•>¸#9êÔIFªZÛsU%muDB$ø`‘#/D¨#9P À”b@Ù„m‡#/2؉Ë% „Û#7ô««¤•#7ˆˆ]ØT’ØLÄù±á+J§¦P2@;Rú.<îÎz1 T¶ØÃÎë`ï`Ÿlptùìý¾² &<ó'c„ÌÒ’K´IDH<öÛ®ÏÅñ?yßB›¢;*wîüP?„Xe#/‹$¤€pôü4çÏìÛ4û{(ë¾¾ìÓ3ÇŒïD›J0Åêp€|ÉÒNgŒ+©™áÞ}øûJá¸k4´š]F8AhIO!$0f¸Mñr£5éÀÉ1(Œµ¬%È#N\ÌÆV,À˜‰#n&šCËKh”‘”dŠ¬Èƒe- np@JEŽ‘J I`é\L%Û £J9¤Ê”ØLCQ´R™XëY!B4†H.Ä(jb#aK)‚¥#@%#/v¹Ì7ÄØ Ç83'¦ï.*/j˜‚ph\Bjmvþ$<ûá;ŠøöNò`ˆ"ä§Ýìý¿|4ç#9®#7j´t#7μC+›q•ÎfÊ2}ù˨×nÂFoG¼=þÅQâ.âîX$d¤’„p(F@Äׯ#7—¦¤.ù|š,ø*,ßC¶¢è#/LÀ†‰·•0žp5!žÒ=†ìUZÓaˆàÅ¡*–dÊIòû´Qó$dž»ƒ€¸ó‘'¿œ]ž#9Ä't‰KG:¢+óBpÜNV±±W]o#95¥Á`P/#9ÆÛ•ˆ³¸ãêí9ac©¡J`‰~ó$úûUЊ|QáíÙv¯y˜’2#–m%¤Ò¥™RÅ1¢Í4[ck0µ„Ùb(©¶QªüUäòmååÊWP!ªtf‰#7S‘’2Ê`÷=ç{›í‡Á™²«»Cm‘“ªá,d v¿§¹Þk ;@Q´ÎœGÃÇÄ€tŒ4á݉°dД´‹×‹ŸaÉø<9{|<‚õl¦]|èõ‰ô?NÀ)Ä•Tó"b—¡ì3 ’A‹9¸/>4dMp[ ¢jKÔ1|¾pX™ü®M8eà"¥¥ê,H…`LV8øSf)Ã×OÓ`µ)m¢jŠ‡1‡gq6Ìt;Ú8[†æ–a»q1ÆàI²’Ë™»2‘6PjàaW#7&;3h$h°aÁÒ_ 7Æ BiDÈú|U{ÌíDZ²Hl´šU&”•3Ú5#‹h"(Ì1yOD®T¸JBiúœ"u´C›u”&6Ç€†Ð‚´’ŒXÊð‘,’ˆ¸iCµ<Ž)‘²àèý½ÏŽTî}ª‡Â mÆþlZ4­M‹â2™YAÍبփŠµ¡‚صZÃi}†e~¶]#9Â]%OZZl}æ0 ¸äE!YG§àùÁÒiòY¯bÞÏ$! õýª©²€¯ð#9-$;Â\ ˆX'³¸ÁßyA$#9öõ„íÙ˜´ÈÛƒAêFÇ"=§µ†²j¨)õú7è{Á¿]#9ˆ2J ŽC)•‚K#7wÜçmçâ¿D™™vlC/b¶†ciâë£u59äpC²dú7äóƒnDì1(E˜8@õ#7wg_†áÓrÄðD,û}‰ÐsE˸WXÇ¡»¯þò—úÉTÑ?5ˆÚ\#/­S˜Ì#/Gá‚ïôâiÓžÃüØ9äö3Å}ˆ|`Óøäè‡~Õ‘êB¦ q’‚½ ¾9ù'ge‡Ñêè¢$"hìh)!“‘âê6#L»«¦FÈÙŸ7y‡ÙîÚôñ¶‘QúøïܯùSGÉõzÄÇ¿)±Â#9‚ $ªM‘QKc+µ*Ô”ûå~Y#7#7IB”¬I0U-BQ8/w‘ßéóèñtpQµ%ÒÑL_*»²'ä#7žØVb, À“ƒ|xc…ÈëØaÐ4‚˜§yÑå~+ðž=ËÙ׸#7ô”­#/Û½`Í+#-! )šÐZ”* Vl±M…2B0?0áíïöWo#7y×ßÃÎ#9ûÏ#»çŸOv¬ªBÀvtÙLýPá"cåyPþœ1ñ¶¼šfàn$Ú’ìÆ©!†žlqŽÙ^žì]¥ùÌ΅㶡ÔRRÛø<<ÉM³,Cb¥”XYÅã%Áž.Æ Ÿø2`8#9(€iÆM†ƒX«¤8²L„”°ìï•dA¬„ÌÆ36“N…0 J…ÞC%€¡Ó˜38Ë*»svÔUÎÔ["Í[Ë»š%nî®î¶“eIR¢ˆ"’€¤Ö`:I5Ž°ÌWG%*ÂC‘m¨ÅFƨÐN»½›ÛˈµJkÕu·SR˜qÀ74ØkX«¨JF#9d™Mfd8™Ž0Ó™ˆ1„b"fðêÍC8L$) 6€éÌZ£}Øl.gòŽ{ä­h]…¡bÀØ>ÂøѶEF*‚n-lB#9dúw19aüœ8;Ƭ3T#9³ñI–1P¹{äÁ5×\“·J@d&ÇT*@Ý$9×eZ׉¹à‡†Ø50ëEìþw‡ö¶T6|VÌGq>¯›š|û§©Œ[¡`W=¾À¤ÞOQ¶³‹QÆpuF±±âÞ[‰q!níxç“ãúº©Ý’ª•8º_ ÑbÞ#7œ-ïxcMü¾Ó3\…; >ݼ¢ ‘EW(¤gð¸7ש1¼\×î­„$šb«#9¦à&E$ÑÇÇ3U‘wâX›)%þb: @àíâ¿ jú>²V]×J“Ó[ØÇëE±'#/œ@¹ƒa¹#7°ã"M>ÿXq3ÒM^šÌÒD&§R™;ŽÛºé™ziÌ8Æ~ûŽÒ¡¾;Î 0‘®™»?GO6ud;„K/–r4¼Þk¡Hžèý¢Q8³yÁMÑÀº#7h-ZN¤–ÁQHXÜG`Ìk#7¶‰ÄùÓÔ'Q@äóbBWgFÜÃœ#9 ø¦§t–i¡éî~¨r9Å<*UÚTi6ÅE5Ñe)·S]5”U¢P4 EÓûUôþ¯/Í}g¬8¿Á×¥ÿ%¯'ÑÝÈ#È]Ý:°K—8Úÿ«êæK©¡óŸT;‰%OU,(775älÛ;ú5CÅlÒÍ?² èÖº „ äúW#7óWÏ“«êÒÓÂj‘£'òIrÔDVí¨²v+çV¶ómAn ”2 0Ý9$½(ˆâúüŠÛ­à¸Fá@ëáNŽ2ý0,¤Z Ö j1#9ÚRñ8˜ú‹æÙ¼×€èˆFˆŒS¹Ð5Oh‚÷ÞšA±dIµ£E°#7dÐï Šžš\÷Ã&ÏqŸo!òdØÆp’`>;ÖI¸B3í8{‰q]Ïâ}BQÚc>Ø=lYì,Üy#/t;Ï"¸ {‡؆¸…6~1(bäùNâún(Ût:U92<ËŽåEU92<ÈäË’¡p¿%$CÈ"’s¨áØEèìÒßNÏr_r·%ñÊQ¬¢ ÄÂR£|‚.ñ¦cò»ødÁ²1òÁ¦` ܳøåÙ@ÚZù?gÿþ_Íûéÿñîþ¯ýóÿsÿ?ýþÿéláßÿwgÿûtÓþZ»µý^¿Ÿÿv“àîŸÿ¿ñr×ÿ/ÿ_ý^ñÄÙÿÿŸÿ¿þßøçÿ¯þü¿éÿÿíØG£þî¿ù÷ùýãú¯Ýÿéúÿéÿ¿âþóÿ¿ïý^j}ê€ÁSûŠÀ ‡‰ûÿïŸÚà À¾€Ç¬‡âæÁþo#9@{ˆr´•wzð:[›|¯õ*dþEëÄß 6Ÿó©g hèª"¤âlR;Nó×èoãSõÝÎî¢ILÌùµ¾…B¼S0?†à*j±ŠG¤¸î£ ž]šm×g$*dSÓB»Ñþ½^>Yd™#/e’ó'þ9CBmÈ ÁºQÞH÷Ï#/íׂ/§åƒé—ý"Ü!dñ'¯a¡ß‡’%@l‘ˆsÑÖ#7ÍyZcYå™E€:Œ:7sR%ÿĽÏüéì$®Sgþ3×y;ò¼숄ñäþ¸ÿF/#9]]³˜RñhT°ÎzáŒ^e[Wÿ\7\´ ¢Át°!æ„ÊHA–5ô‘¼újå¹O‡xˆç/ÿJÝF¥‰‚´Ç2‘µYÜ­™Ÿêñv–½©SRª ñJg––™E¥ÖB©¦˜)þü,‡ŠTÃ!ÁþýÅ¢MUO FîÔ«íM"eâÛBîó´äZ!¡W*•§góôx¿ta¸#9c[Ò»›0’h¥Ñ¿û”#7þoNîË+¾ãG­ab³4DV#9°=˜©…&:òïé‚CR{9p5 MMbáÊvÛWŠù9ûŒUÙ`•¥ã=bc·«N•#7êU!™’8qö‰Ô‹ÉAyr–á*±°ãKâ0úÿ ¸‰™Ãÿ„inÙüßY#9ôƒìÌa#/çZ<Ü÷>|^&z¶||(FT`†¦MÁ?)ëëÿ³dÉ”èz:»{³°Od$ÂääSѶԤLm ÆâDж#9¢­4¦V±¬•ŒÍ$H° 35ônÚºÚ6!õH)ðäø”å#ÿÿb#/Ç¥StU§0X" ¥±I”Œ 8[¹b¬ŠqèüS»æó¿ÿŽÞ9Bþ;=—™ÞFréIP9Æf?ÜçD2¿ˆ5Ç»K®¢ì´*©"(”ŸP–Þ>)5ýfz’ã£4ÍàëšyŒ‡Vz2C$nœ0¶3oÿEühmŸá¢Ûð€^°ŒèÇ"îÁö´íMö(;ã@[å%®ð†=#qd°âÆõ4¶^ùPû;ëo4%§4ð֌嫽FX$¸Ã¦4êñº!¶j8,'ÍE† ‡Õk…_ªÜåp|±ˆ„­Ä•è,µÓŸq—ÂZMîÆíËô@ÂLPñ…ë8ÃI©"¨_2iiJç d M:…v‚Þv$¤B%¡* ‰!¿jº³v mÖå”°qpä‡71Fg©d9èÄSÙÈtI÷ï‰×`á ðñæ ãR›e¶AÎFgdÞÍÉ»(ó(³à6#9i#/!‘RÅxôè.1è&‹%Ǖ׋•IGP ÷ŸùOx|6ö¼׿¥K@SvLÿñ½ÞÿÅ°õòO:=¨ó}˜_|l'õ°Þ¡ò)ös?ôÂŒ2‹ÕêÃ×Í\#9ÀL–@… ™0… aÈb%’‚!ÝÜE>B()J‚x ËÙô|ß×øt>LCþ{ó ÅD$ìðø!ð}~Æ·£¦¦eñ²Óú=g8n!¼¿²:_³zîåéñÃˇ¸‚úaûíÒ~¾?¿ÛÑýŸóŠmwvþþpŠ¡R‘î3¦…:Ÿ4#9RÐQKÿG¬#9yßÿ¿‹¯MCÿà“þ£Oþþ=EC÷²ØLû;?ûÎÞþ§ë šáã—QÃh³Æÿ€¨ þß,|þ>¯ö»o©~ŸD>Bì»CÊ#7}Ó®Îéèè!ûWküïû+GàŠ%Mbå#9ë;ãíáò†Uïó³ðéGDêRAþ𔔶‹YÀé]¼N*ˆ¦pM÷j¸\eœÁ©‡|Ž!ñ÷í:vÑ: ¬¬W9boÜ1yl%øxF‰ÅDµåm9„ƒíöðÚlñ9ØpŠð¥‡KA„Û$@3\„¡ œbÁZGC.—††Š$\ 2µ#/¢scƒ #÷þÐWpÒþ®nÕ¯ÛÿË’ÑäS×ȪÌb‡¤ð0<þÕJ ŸË° >ëum^6\ª®ÀÕ/Ô-²Ôö¥ÁÄp_Æy?_îÿÈ/÷!iXûh.@@ ÿx_ÿÚ† þÅ?À6ùÑ„fqQÿ‹¹"œ(H¤„¼#/ +#BZh91AY&SYL7Çʶ9ÿÿÿöÐÿÿÿÿÿÿÿÿÿÿÿu€ †¬ 8ÁX0E‚¨bQ\{­½÷*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#3Ûo­K³mCam¬vu¦­eJ…¾wt]©šËSf¤§:µÖlÛݶq:ú¶»}ìúõñÚçS¶éÊÛ¹NíNݺ7ß}íàÚÑÍÛ¡ï{;RR‡]#9­ìÜט½Í¬§@aحٽyß_>´€gÞv|ÔÄa­Æîxoyïz®ÝwÝàòó¤#*×Og»²ûç¹àîÀù»Þømîûí¯·o¾ÞlÛ{®ç3wŸ|¯#*#*#*#*€6 >=#*¡N¤{À£¶rì#*Ý»aÝ­ÝÞÁ wší©¶Û+Z Â57:ùÙ¦ImÝ…½´8«F‘#9¢ƒCM»†Øw#*¡DT¥#* ½î"¥í’DPTzžR€J€ïnT×½óz>Äø¾Áç¨ïw»s¬KÜ+ªš²w*†ÙÛ®"¤jßO[œpûšpßwcÚT×>º÷™Jž‹zåzîÀ$¯¯—§·Ùcg½å×¾½ÜÙ»)nîm«çÛÞfl£&vûÚNûÝìkÛíuuë×E½µ›ÛžË€R© {7–µZ•Û®ØVmÕ=ïzǽÓÎXë®zÈé¥tÞó‘ïn9§¬EQkÝÞó^óE@”‰^G(c:uJKk×/yË™ÓÛz vÒ>à-ï5ò÷΃' #*  {Ghν{{'$·Žöû}ìô)îç¼#9Þ9ãÂë4ÝA÷Þqä0ôúùvÚû¾ú€¦f[¹óç5vNͶžÊë¾·¶zídݦ.Úöo}]Ó™}uCÙŽ=œ)ÆŽN†8©rÞ ˜#*7—«Çzu_w}ÝFïz§KsÑH (%;5I¢B¼kl°ÄÛvvë6É—ÑK¼ôÞí½šݹï÷¶YÑ{Ýžzoyµ««¬¯‡³(Wº»7UÝÍîvºÝÞò#*#*&»©#*h{Ý{Îñ^w‰ï}Ü}EOp[¹³£;nøşj¤ç=±ãÃ¹Ý íËÙ¯ZP}Po³5Ýïz¥Ski‰«TsÞñêòêžÚ½Wºù·ivë¹o#*VõÁ{ wló)´ÒìÞïN½wGk¶^Éغ Ø…œ®ØãîÞ#ßYëŽË›X¬Ú.î+Ï7e‡»}¼z»ÝãÔmÇijMìWœJ[p^îçtîà‡St½^ÍÛ{•;{={×ÛvÙ^€&–ÚÁU!Ü“¦ï®æ2ò£#3Ën÷tX{Ý8zÙôk½ßNë{:¯¾ð>ù·$­©´Û­×;a·}öÝcê¾öè:4#3=#*{Îtöt°›o;¬ïs(îX;Ðïg©:w4q£½ã¼oy÷gl#9|íꧠ#*$=ws«`ïx#*#9w˜eæ¯5›ï‹¬ÝÛ€t¡T­P*•=.íÕ–À1«½ÝwŒÅÝεÜ=³fÏc½µ=Ýjc¬êîÙÚë:#*$H»W&]6îtèºv´Uf7YƦ6ôt‘8Ot7»:Í|¸xØwÏžÆôì¾Ûµóö¢ØšöÇGu÷xö2ÞÖí«^IÙ½÷¼óêÍocÖO}‡ß^ÛZÌnûpôøº÷¾^×ÅòŒš_øšì4Ñ#*@#*Ð#*˜š#*FM4i‰6‘¢56£Ôš! #*zF‡…¦ €A2hhÊz6S'ê=OPyL51#*#*@#*#*#*$"M†4$ýL™LFFLO%G²›JzÓT#3<£Lƒ@#*#*#*#*'ªRDLM5OBjòQ HÓÔ4 å4ƒÔ#*~¨#*#*#*#*#*#*"HBhÐ#*MÂ4Ę˜ši“Ò4Õ?ÔÒSÅ z#*LS@õÔ#*I¨ˆ #*€#*DÂh#9mÔôÓRi²FjzFÒl¦†€Ð#*#*#*#*ÿ¦KôÚ¶»•þŸs«›jŠ¹s:ý¶œ˜DK%>M[NˆdHŒÆÛ$÷­ªÜÚ«D€ªzV ©óÊ?GÑoœ-õ[çF2˜¾V'Õ–x¢* Š Xu2F$ý>.bÞêÜz¹t¢­^ť°ž“¸…bÙgý–èTCz#9@EoËt\è¹W –‰|ýô+Åé;$šé!'\ÁÌõÑôõeÄâêëF\°ÖK»¬3‰«…ÂLs†íÕ—O‰5™»Æ5¼ÌÝç]Ë„3¥ôüÄÅ¢ƒÄ¢±k=5Wjwk]dɲ#3¼WZÚ[QmãjµÍËk¥ZÌÛkZ±U­‹k[R#9 ""Q'9ÎYD‚ŠiöÂà!‘BG85[ ¢(¤"|¢¥À‚˜ªBÍ[^UÚZ5E^û¶Ý´UêÃDsQPÀ$eYL˜Z› Ú4ÖŒ²Ršˆišl¤ ŒIMX™•–2-)F”RÛ&‰–,Q’ÔÔmYÀ6ÑšK&šDhͤˆB£"jR‚@ ÚMK#*ÓI¡´¢¢ÄRl–¨Š%›Jfam#*šM -!²C#*°eLÄh6’6¢Ú(I Òl Hƒ¡+1(#3£K-#JZ-4ÙÚV¶mm¡›XÌÉ2ˆ’ ²U•YfÐ)i4T¤MMlfÔ¶ÌÙ–“$ÂHѤËMFM¦fh±*#9$‹"X´"F¡ši‚‘1&Š‰‚…ˆ±IS"3JˆƒR˜‚ˆB"BÄ#3¡’FIR&B4±BÌÐÉ"E(H…2#355f˜‘A%"ÉK2Ù5Ñb‰„YHd²‘bÓM ›RdSL£%&M#31"f¤£HͦcY(ÚEˆ¢fI6ILÁ66É Ø‰1M)›ÂÄmI`„˜ÊÂPÄI)6-I©( ¤ˆ“Q "Q£HE"™0Eˆ˜d1’RDa2˜ÌÒJME™Rlk ´¢jH’b iM$ 1²[E–e‹2J&ÊdX¢#9„dF’Fl‰ˆ™jiD)A³,’#314,b#c,l›&-T„ÈÔÙ)D‰-""m4È0Ó64!$©%¥AFLÒ6ÈA•2ÅÖP’Ê#3%‘˜F,”™L&™Hš#9(јLÚP¤ÅA°F&R ™Œ’1 ˆÊ„Ål“*fme[)¬e0‘¥³bˆÍ‹(TlÓEIŠ1&I6HÆÆ2TÒ-3EŠˆÒ“6LÌ–Fmi„¬D`ŒQ&“`)©¦i†2ŒR4A²%Š,Y•)’š"Cdd&LŠVCEŒF2Œ¤…,EMQI&$“JmMF‘"†‘°&#&j4Ó"mŒf Ù ¤¥3!³" J’”Æ”*iš³eb¶KI™$Ù# É-EbÁiBȚ‘&C‹1 ÂL°jK–•šD£M2mJi@É£Za¡&e&)C,›"2˜$S!š4¦1 5„Ù3&D†ZÒÕ´`™BjfŒ¦I‰¤Y”“2HÅh5)l#9Y¢ÌRiBYR¦ÊÄmL¬-š1$b&¢)J"f‘¤&š’¤ÙY¦±0ÖoÙíÕ˜¦eFš[# SJÓh‚Ú–Dm4™6“4Ú•ƒQfÆ)”fÑEXK© ÊYi¤¢•#30ÒÒQ°’jKTÄa¨FLe˜²šT‘¬"Œf$3L¶KhÆ%&›XÑQHZ2i„KY‘–,,m ¦k4É“5& ØÙV‘QSe¬U&YMc+0¦¦Äf3*¨±dF¶M2²%L²›Y*Í°Êi¦XÚ¤hbÁ²‘µ4JÈÑ&¤Ò)j+¨*£“kE&Øeˆ¶5dÖMZ*űh©bÅDSIbÅ‹F65¨°ËF¢Ôl²FJ3`ÖÑ°i„”R Q¢Œ…¦I¥iµlhÚbV-I6ÒH[Z¦ÛY±¨d&S5-dÑ&ÈÄ„JZE”²E¶¦¬ª1J[5M”ÔÃK1Z™m´ªY)dÚjPlam$’™f²Æ…†²k+6¶6¦”E„‚‚ME™$…¢ˆ±`M JH‘#9ˆÄj£¥±S*JÌÐ!*(dÚŠÉ4ÑE&MTŒM–)ÙH6DVY ‘LJf%†EM2’P¢Ñi¤„ÈͦÒbˆÆ²Â)¦DÄ…hÉAa¡‰ ÈZ"ÄhÙ1 ™™´QbJdFcIe˜ØJ˜#F“a)R›$&¢Ñ’!#936£lÊI(ɱHS1SY")…²XŒjMIaEhH¢T!FKEPšE!˜“F‹2›2’•3Y†MbY¢ÉˆcR-EQ³Z3DT4jSI°Ó,Vej4 ÈbQQ˜›Tš“(ce4ÆÉ!I–ÉL¬ƒTRji,›²m(‰†”d´ÍXª‘hY˜”°b, Ù³C6Ʀ‘±FˆÍ&ÉLBÄÄMI £h¶¢£QF*Æe°ÒaIXFY4ŒR’ j(زʒÈS(‚ÅFCDšYIS"-¢°XÖ¨’¢‚YTPV4E›Iª-L4BÆa5¥1Qª-4¦™¤BŠ4IÌ’ÑcÉ‹”Ú©YITkf‹&’)™B´¢Ì•‚J›ˆ™m±¨Š°h©•J‹S4µ+m3–5)k)ll%¡¢l’”ƒ4Ô’BA ØÉE¤¢³,IDb6ÉHjC&d„³ h!hÒš™´ÄSmIl‘´¤i#9i)¨Œ$Q£lM-¤ÕÊI±²bŒh¢#Il`É#3ªF,ÊË-ŠÑ&Õ¬e(ÚKTˆ!ª6Ƥ¢Å"š"™‘˜ÓR#©›$ÊѨªKY*Yk&´%h mDTQ$Z¢™TÓmEb£Z‹FÖ“1”f&3¬¬Mh¬m4¨¶ˆÚl¨ÙMªQ„l”#)#9´ hÑ`‰*,i-F±fX’-3RVÅ“jRfÚ#3%bšEc&6+ª¥­b‘2¡Q1%Š†XŠ6)¦MES#9)%XÛØ´Í[F5¬´•42ÖÊY6ÔÔÛ!mFš±4eDhÈÚIEPÖjJ¥36X#BDbI2’dI‘ˆÈE©+DS5Sô?þ/Óßç5¿#D\Í;°S.¹jÐß®J-³ýÔ?Ð쟡üj>ò˜ŽlcCHÆ¿bf؆óýÑ¥ÿ°Û]¼î×MŸD¸Ûô÷cxæý?§¯Kzd2©i#9£þ­ø2ÁaþÌÿ‡ë.CV Ξt`ÑþüçF“ ˆ\¼hƒ $-*ª‚ª  /UIÏîåhÁTõñ ÿðý¶´Gý&ÛMxdÆ£/‚–1Ð硇ü{ÜàóJÐPðœ>X†ºql-­J˜Jƒ%=×AÉš±i–Ääé™ÜÃ+c‰F6±va·'%ˆ²·lÙ©8U²Ñ#9JLU#*•MÙz4,ÃMbä±Gµ…6%#Â&HìƒcM£#2ãRD6_ë.ñܲý.¼üN³9«‘T6¢S ³Éš!”íÆ—  RR’(šUÔ‚2F,ŠNmÔÍÎéFsm,°ÊeALå¨ÄÓi­5Í E$Eíç¯+ÒõÝMp¹qÊü,°ÿm€qp‡ Êc#9Gåt\×ÊדGŽX_WkšKb1(*?ø¨·/x<^¹£A;Ý[b˜`ShR,ž<²Uãý-C¡EOø½·pk½c…(`¤q›‘:Ô’œ?6•x¥l0Ý Né-BJˆ†JÅy÷³Ù¹´Úú\¢åRSoÕÚÃؘÖÇň5«KÎæXg·yݼÄs—NéÆ™\×4ÊÔUʺyÜD›îξY­ËFˆ¨»Oµ×òUâü r)•ò9 ­Œn\ÆßûíAá&8ÈÔmŸ_#9„BdGļ‰Í#9#¹EHŠc‘ hg§,hë“QÕ‹}ôR½#3?kF4­¼‹¯¡ñ̆+þ)†ì:i‚ÕH*8¢ÁíÀØd>Ú}šÊÐgõ!l‚È»QF(Ën*°3Û_nsÍs_V,[èíi“tEYÀIP8x•26`ñ³Á‘Ô^ûþ¹$Pi)©ù5"§V«Ã¶¼àøeÉè? £9nNÍVmâ‰ÍÕÉ£'6I}+ÝuÁ™C2±Óú¶¼ìPW…} ¤§:¸¥>8ùïÖç¡| íÝ­ÛæsëmË ž6®m|Ôl“ɺÕFé‚“F‡ ù¥b¥#9P´»­TOd ™Ûe;ä6Ój4£<\m õQKiÒñ÷¿V*v+–EÑ5K*ª Ú‡Ùœ\O²Ê•S’\-çEeà–—Ø×·yçø}Mãôé‹üÇXfŠDçEtP 1ÐùPX†ù­±+WÑ'“OWn‚^î{·žºzÑÐ0œCž¸¥œ½Øyµ8öOçôE®#aø…p±Š/é½7,šãjäý_uXž•KÉ FCD)b±òßÇå€ìÒˆ°j‚Rô¨#9ÅRußú¬&¦i1ˆ”ÔR|Ÿñ¼Wxê„¡”4’˜§}Ñ,DM¥ÖR €½. EÍsQ¶Þwѽz¼ˆJ²T=î¹±h¯Ùšº÷vÅÅ,YAg“HŒåF»bZµT-ãcQRmöŸSx¤´E’ß#…TX)4•@šÄõÞ¢ÜWf›Ù€d÷%N5–ÉM08m@Z?•CNeÄÍkf¬û’L ƒúÚUTAQ#*FE«P6JÙ¨-$®{Ùxh‰Ü®—77ÁÍ=uëÊäåÓ!Å´‰ÛT’]îÀÉçGƒ’Še¤º«JEzwÕ¬üªÔðÐ¥›ëá¡…9:2õî²Á‹ Á¨¢AMŠ(SvZlÓ ªJvœëJ» *6KnÎ)i6I«.ß/åð‡æ(*‚Ì£ö·fî<$›éG÷ý5?vÚoÇŒ‚ÁG¯q•QçEO±%xxXZ<ª…ˆ(¤íe(ˆáv¨EÕ„;ÈüŸÉ—ã ^ÛÆ~[ãNÜì: ”ØM²é:Ž••J˜báÛ.8¯»û\ùWHaÍ*ƒ¦œ% ¹w3$˜w¾ÿÊbZj“V¯fömíö¼¼ØµII˜Q™AQùp«Á|«#peKbƒM+>?õ!yß·I}ž¹ž¸”òdó´òhÇõI:W0h•UUPô»BòЈˆùµäÍ]1I¿*¡ÄËÒÏ£n=l®)]=3FJC÷2MX /s{u¢1\zQeUâ´~ôš.HÃ$6Ñ,øX}ùnÈ0ƒg;‰jCñkwyÿ=Bl¦û£ì„uFÉŒ ¤,~¸2§.zÕ:”é\oÎÇÊÃ.NM›(SÁ?‡;碶X$M²&ѳõúì-z¾sP¾Ìñ\—Í:¡kßnØ×Ç×J~\è“D‘aÚŸ¿YXF|Á æÃW¼ù˜UÕ0Y«+d0…‡±þ'¦%óêÈÎ)l8ŽÆÑbòd):ÇÄ#Ʊ²ÎpãË:aÅQ¿­Á»3˜ß*¼þîsu{Óº.AãHt¡°îŒ" &Oδyíï.2¹>ÕHÐþ™Œ²=vÃÀoÑÖ♢å¡HyV,¦tï«]•iBL8#9£êû.ûS#7Zí¿•µ8žúé—­¬¤áfSÆߪtøC5=L¼ôp~­è¼ûJ] `°!ÇÌ#.rš¶W Ü>iºæM!‰-ØüΰnÈcÂ2¸œ‘?„›ùf±Z€µ™íÔ©†ó®*r˜ý™/ã½â‹NÆiãϳ`WVo>ô—„½Ìl¥Üt’eGÂ!c²ÀÑ7ÅCjÓÇ Œú™)f©Ãaì©L}:s‹Ö6qÃ¥­Wÿ¯,ŒÜ›bpn=ÀŽ(vÑ•¯[·t##3ȱžgY†Ñé§%$„ÿÁîLB¬¹Öö;ÛR\<¨PùÏ™tjI#n(¯p©ëÑJGåQŽ´Úºh·.Ön;¯ËöYÓ¦oÔ„™ØÓƒ÷éîcŒžXgð]R1#Û¿Ö8é’ëæᦜlI¼U#G‹G§¤¾!µÇ™ ¦–Üä™!C¼Æ¶Èѯ÷¨½v`ØØq6>½uXƬƒ!Kµ‘ôû¾ˆ¥ñ¾TJNm—*Ÿzó‚]ý8WñÙ ¦°©ºO”ŸG?ŸG[Þ\»ÔtlE„`±¡JDN´ÍÁ±°)ó÷!¹]zîÏ™¸Ê‹éêêm¤&÷]§^ß_›Ï¼èîãºïõ]4"°&|¯û÷_ƒ÷¥ÖÓå÷÷^:µö´"¯¹‡Ô–Äù®Ûóu׈’#9#gâíÊþKW¬©ðO¿Öwš`û¾zU¾Ê+¹¥Qàá™ý‰›Cé}wžx ¾Ê™$Ms#3ØØýèÝÂK·PÕí²„x*¦¢¸)™ð¨_•v±ÌWÙ¢d"§I‚]ÚªZ¥åüæ!(Ù̳eÊìwéFK¥ªhP`/NŒkŸ²ªo"9f~H½­8Ÿ4t°‡Û)MEoj¯O#f.Nþ'AºÎ?Š.£ôÝÄ1b3#3>c(QPGWvº»ñ­ Â`áG×E"¢¿š`fý™¸úQQx[1H²4œêヲ詥YíÒ²a>mÛ;úxÍð3m/ÓcîhŠ §=ûâÁƒ÷E§SÒ¸vÐî˜èìòíêÐéߢ"üô[]ŸÝ€9J§'½p¬\ø”PUjÖ«9À5dáÄÒ2T±(B3 ½ñxb¦‰\Jâ˜ÅWèe1¶¹59¸5'‰aCÆñŠ)2dRf“qmÞ¿I=ºg ™-l ÉT‘iت–UèÓ:²8ôÅ•Õf Þ‹B"ƒëIc§Ò3Hˆ¢¢Êj Ãå*Z½õT‡“7Ì¡"‚Ž©Û¹ˆòf‹é¤k»Q±qG«C–#9EX@ܪ•ò65ÎâýkÍoJò4†1S¸£}4Dˆ KÁ„¨WÊž˜\xPÐý­xyÊ €Š¨[Ú­ï›—á„9Ù…¹DÿKRaŠ°ãHêý(k~û¬W,• ÊÕ@ÃJø©{ *®)ø9šÂÐæ’ÁêB"ª±RÇ"ƒMêttmÑÝÆ(=}CKcGíp‹là&¯‚NÛ³¼;}XUâÎwÆAµ™júàkËù÷ô×6¾U²[ž5f¥;C-æòëA†pqÄ©(„znû‰«n•®ô=°:%b\láÝ¿Wegö>U‹ä‡ôq³¯ŒJ%.÷ðá ¢ðá~÷éUSí1"aâÅöËáÕWtõß퓯ߛoê[QÌ/"¯QÔn5 Eu6³òIDp]V¹§f¶‘Ag%7ÍMûì£#*Õ4U¹ÁSƒOÁAŠ",œíŽE#ëøÃ_+BŠã^»¿‹Ð†Åå0§ÚÀ(gv6Œo‰m¡Õ£¦§²Å¾%Ž9!½ÓîÎÜC™ó×gµFôÆùs‚#3©!ÛÛ•/°|#*’?w9™ã—Sïëïïv7uRÎ0Ï—iŠ?:ì3C4»H>å±×r"P±‘1#*øNNïI’êƒ­Ö Pé&‰NA‡q$îÏNú+çU0D'ú&^ôÊL"EBµý<°aC7jrŒæ9Ó­×®Š¯Öɶ)Ö…Z|ä1çÍZi{¤zÙ]ݶºy/#9¼ò#3#3¥UG—ã=i»\‚Ýæ5–î’ó¯„zC¤Âèöpr–!hXÒŠ‘=Ê 1y$j0)²8°…ÊVb0¼\9®"6xA+)­²oâ©œS¨4ž[´ˆ±:«ÌÜ–È%:`”šçƵÝ^77‹ÙÝƼ\‚0{šMxbÉZâÌ ë›—¯ô}¸<Í(ñf°TbÄYý]3od;»#‰œ¬$†ñ±ÒX˜èç΃J}µ‡‚r™­ªÀÐJŒ8%ªrCñî­Ù©ã­Ÿbh·ÁÑα#3jÖJ"F“ŽB„|™rL¼<À…ßP´ê·É8Bþ¡Æ•«ŸÓ㬾ÙÂ#3è«rž#*¿áˆ‡—xÈǵHóL1ÿ6o§·Œ¬ö§Ý‰¿¿†½rmí,ü¨§L“â©~úœÖþ×8µ(–:Ñ\Ú(fí¬OÆ”§íÖ“jÀÛ{åæØýû…fÇjIzJó'j@Ó¥V"ˆ³ÔÏV¡YÊT¿‹F}U .ŠûÐ,`¡—c ¸²€çÆÏv¿m§çï°3Ø£#`#öÄÚEÅä´±º<¡Ú-o#9tž‰#*Äb㳜¥ÐôÆjÐ~ÐGmƒL˜üv™Õ<[]µ–ï)'DÖeÁ«HêŠj–Î[8o1·³ç ~Å° ÙEBr~/HM%‚#+ÿU10b¥]K»â¬#3—R~jzÒ™Š¼àÑm3,+ñk¨ýsg“ÜEƒCk¤‘3«E+m"q'„3 !Ò"SBÍT ×x“ãmÑWÔã8[¾*6²¡ JeŽ`mÍ‘,¥g¸­¬¹9ŸµYá`¡#;Ãó—×5˜ˆÚôȹև*ŽÅŠÛ¡IQ1AËÛŸÇ-hí¡a³»ª¾4ÖÚ6ÇnH0òp²IÚ ‡âèΟ,kJ&‡Ð?Æî2<ý#9¨ñ5€Z¢¢køSáH ÔNjDuq¶xµšÊÆ+b>pÀÓÔJ#3’#9#3¦Æ®}ùΫÚìT¥eM^;wnoµÈ¥ÇU×']eçѱ«‰‰kLFéoôùûñƒÐh#3>Ãs?f=ÐËìåv[ÖŽñö1$ø$’䙲‡nð’§V@É>k˜ùB?.Æ| Qq±RM‡úÕ=wv|Dž´Ÿ#À’!ãoàë§ôŽh7¨»¿]ZÿöôîBEÃfë ;ó ‚Äpžý‡`x¾ž¡´rd®h*QÅ‘˜7’ áFWÙé?ìû8üËànþû69F¥<Ê7mËÂE¾L²c£ðîä¬E¹ð“½yÁîøÃé6ék@2ŠžÈ9ErtSU„Ñohsz[ÝQ>‘•)“fßìšu]PÍf8uŒÁ®[Â4íŒ95w?g+©ši)se {-pÒ¦Žégß7ºV`åÜÂöÃÞÑ´Üm#3” tõÛ#3²8¯‘‘`¢X*ZQˆg*dCâ–X³Š·qÿCîÀYoÐ"©õ˜zVmþ±õbœo‡í–š.—µ4ªâ]#*Ì óüv>v.5bÕ£CæmÆQ«ƒ8 ù¾¿¥ÛõÍð¹Ù>ˆÙã‚V”/õ[µÈ‚oI.5›¿Œ#þY´Š½Ü±‰Ëtç\J1k×îµh`C|Ê”‹•¾Ûi3ZúSŽæTB4îaq†«#Ý÷Ìíc€’Arî-CŸOÅÎÒíÎbþnÛMÇuÒŸ'Â[HÕÅöÎ2{%=ÙÏw/f(2G ![ë„q¯u;s÷^e1õQl’a”¨$¦kÇybÆqv…w7¥I›”GË ðÆèI[ïýO˜Y|'ŽU2îøæ­ïÖ`¿'k òås³JFS Õùµ]ßÛFºeû²5ÄÆŠÀøEö½`AH¥W0qåÙf‰HeNíŸÊè̽U^¬4Ûû÷x¨*Efhö4Ûôæï=ÕÁÕ2ÅÓ¾¡pS²¸¦q@ØÒvìß½ñ/Z+õ¥>:­ÃäÀúf¢Ùø÷? öZÝ:rm~*ÏZ—eËk`éqúa+¡h"[N]EU8‰šÔ(±—Ñ !ê›’D•?ÚÍCO;g$6ë1öÜ‚EA©bäû'äµý»Ùwvéæéú=h†¤qÚ<·Û‹gèëÿ³o=sÙßÆo•Þ5‚…>P$RFÓ@—ÿ^¬ì©Î:$ÿªné¡ã!ft#9`:\zÓåã¶ÊsdJ½Ö|HÓ'[1½· Ѓû·h[—;7…ï?Ý£ôÜYª?#3Í[Ù°öl¾7òQÓXÊŽZ_r Dß8tNfÍ+"Y×EÿÄ“ð)^Tqö—ýdONÉ×›˜êí‹€´r¾b4°sã2¼_eÒ¼ü0:Ö w¯7Û†¬'bÝ4¬)v¬ë'è{Kšv‘„áyu ’Bå»e^yÄ9‰k‡§ôC(ò爻TË‚´2a¤^àüÃm2uo¤×«Ö®<¿ÅÚ ·–Cß×–ýÓj,s7XS§qÄ $43”¡{•š^ÎȜšš «rÆPÙ¯D­ôÙ%¯±›ƒøˆSm‚Ûù¤ E²j¹,½$ÖßµZÔm°àé˜ñO„xÿ§x<ñeõs;b'£ûºzIV»HlHt,ñ½¶‰Å±Ê×9㉱TTû#9nÌiww%\êÕ›ý:Õî‡c#3®ª¿Í”€‡áêƒÿcÄÆÏšÜþýùxÈÈÙ:M|œº”ÝÒäc œÈú?©“ËÅfBˆ+Єd#*èSΔü`Q:­8sª×}ñãÙ¸ÁÀƒLÔ#÷¬õ¦¾×|Uݧù¬*||œ>^49hÚ:Y°l¢d,*¾0Fëü¼o¿sR‚\ˆ ³•7ú5„˜ôÜ$BDË §ýˆÿÊþÀ%‹c#3.µØ¬¢ñòݲ¨þŒ#92n’8úCr]#9¥9áJ g™î,:AJBà–¤ßbw€öHYêèxäÝ…‰&éÙöºg£Ý¿Õ‡›v»‡k˜o']QP0wùñáÒÌÚÃÒ[)ë¾×Nïà p1#3|£y1¾Õ#9šI#9/J¸m·K‡äpsÿ>ý&ZÖy@„$¨ˆB"P'oî˜Ë_ë #*_LØeè¶@â%œoÑî¯ W£L¾ë›#Ï- ž¯*Tî1Ëàf`5«–´U?ìì×ö¸Z¿K›_2.¨Š#Æ°¥n#î6Ñãt±ØEÓû¼ðߦNQǵÌÓC`Ƈɑ{£(È¢)Ëë>»9‘€óýž¯MSFS\E­ëõˆ#3xF¡Rú:n%ößòqï®:"Þí4ÔP[l¶ˆÀ#35ÇÕs¨JÂ>ó«}¼€"w笆âXd"£:7”cŸ5ó6“ÿ3Ý’ãaI}”‹ž¹6yÐ[ ¼qT6—„»Kc—Ç?xZx«((H&™;ä¥Ù6…ƒM2U¦@TAÛ·F3ØCïŸÚ/° '“­&ÂóLÝ]›#3-&IKúù6g,ÖòŠ¯ådIÒ;ª±1SÃ}¼Ï #97ß±áÄLÌ^2Ì"¬›OÃ?0JfBêšPÃ^]–žË^óÏã¯mJèlÍ÷©7î>¦Qé-åýo(!qž™•¢U`Ž B&f×<±#ÉÓ¥Óäåžš°†1WÕò 4´t¨=øýOL•œœi‘¬=Ñ΋–?Òþ\ËBˆs¹G‚ªß>œ£ß¬¥Ÿ.ß©[S0#9þ¨dïTƒ–Pˆæ'K2ηGž¥Íz{v¼žŽ÷é¹´ä9°€d’–kAöø†¬,!nÏ¡m¢(¶Šl6=b©Œ~3Î<ðƈÛ:åéŒ$,nnJµ³ž]šX$Ý™áEæX‰ù¤?ùZ¤;¤zŽÍ)³8ëÛc ´•¹ôpá"–§Ó{ѤذŒ4øtû°nµé–Ö·ƒ”N( nœäë!Œ,4ÇçN-ž„żŒ™pz›ñân Lè<°æšRN(X•»¹»»YÄ)%»ú[0‚³]ôx/¶=3‹ÑÜÄ@¾¡¤mˆÞ>VoÓû,)˜Š3…5Ž„ÝC÷V—í )#Mœ®÷áø0¦Ú»ÚõÎöÅ­9Ò¬0¹…mÆÐ''‘`z#*…´í1( €¦×4ygR­ä]òÙÓùÍœùîM³ö Hø#9ÓÁŽ#3Ãio3ÚÍ&ÁøL£¢;Kcöv©='M0ÑàÎÒFÞM|ኟ¢Æ„OJÑuñèoÓ4ÞɃoU‘ ©j˜!Áo‰¤šâa‰é—çe¯ªFûËËšZVÎã´á’(FÏ…‚,abÌHUy…ßWü ºmeúá´‡NщLí<~-HI%óÉœ•µP”«à#pb.¾\*úûc@äÍèÞ7+N˜[#9¬ç#®P¨FP ò×YÚ–2új¬Nú–~”aŒn"C6âœa‰j÷{ÏŒÙ?»`zg7ï0IÀíðòä³!ñƒLJ†˜sª=<ÿœÆJ,]@è©ÇA#°ðþ¿cü«ÛÀ{lemþLL½Ì•í#§Jð¤Ö!¹×ËÎW»3”Ú¨ãÕ³ëXÔº,5ÇÙH$wæPNô¨ÀœG‚ |zÿÛ…m}M‚ësÄ÷‚„Rd‚…n˜Aì÷éXÞ î§\ó<× ­ÊÜjÓ!;>N¹Öò>é©.NÓJ&dDb‹áaŸsW×:8‰º2Q` 4ŠÀª‘Y9‘%5åC›"ÌbSJ‰l,al^;8±Æ¦@¥‘Œcb)SÒ¦7Ž8£²0c†”\®f°ÆÁ×M¼xq®:f=ÕPi9²-×ï¦ LǶ<2óî>}òÆ|s2»HÔÈ#Q¾ Ôß·í7â9Íl„ãùãˆÆsðþ?ê°3ØÌ*#9Ñ:A(#9#*ã¿S˜ ¯{“Ÿâ¼cÉéþ¬ó‡zŒ5Ì7f‚ð<ß+é’#9éÛ(ØšH#*±^Ó#*­ª¢`,ˆ7P Ð ¸fBÅyÊ<hCm#ÉU<ÖYXDZÛt4(³±\SAØ0éE)<ŠrÓ63Ö2‰MÛß^Ûb<`|1þGåã).IÔ¥ºVŒ(¬å‚Ô [T&Rì³Í×Z\,J2s]xt²`Vbp"õÏWé†y°W8¦kF©H@(W*Û#3Q2Â"‚“–©³¶ˆÂç†"ã(X—bk a È©Ó{‘ð @th[ò\€’WcP¢¥°£hc%EÐYîÎFħ;B¶SZ²#3‘ºdÈ™óįËy©ïn—’¯'x}v¾ŒcŸ<øGw–×5»¾=Û(’tñ#3íNrÜr4èÈ+:un8zÇ~ý‹›Á%åð1<£ƒÔÚw¡¡2Ô8$¹ ˆjƒswF!Û1©I:¥’Žä:2é‡ #“C‘˜¹ËÔ!L;l´*‡œ;±ªÍÉRãp fñAƒ{²¹4{µïÒYé^W=å¢)HHâ•Ž\ñõòĵ£ÜÔdíèW4sƒš7He´w|#3×ϯm%é€î–Ý.éƒ+בѺ¨ÔóŠ²É·Õ…O„½¬zñFu㑺W« !9w! 2©‡»ß'éþÆ’”XÏÍ:“HV<¶¼ Sè ²OE¢>µ`E64èG¡tPÑ,€ W/WZiw&¶‘è:ºê6†€q ÷(úcàÃ^X°¶€»¢€=Õ#9Í–2xéB%ë»]Þy—k»ºÓÇa˜ÄF‰ÝºFæÜ´j4”%9•~Êè÷'‡~ši›új+êå|æ©xÇFãè¸CR@2˜EÊ…UP°e˜—‚Ì#¥Z$gOw»^í ¤Ù0mP¸”ˆ1¸ã @6#*˜± N 7¸hó«l¿ÉõyáôO>œÉªºtÅ,o«Óª´h‘DƒØnˆž’Ùk}*2;ÒQIÚIÿBiVÞjHbéï¶îæ›=9°ìô;Õõ‰bEj—dõ4’P¸ Ånz6ÍpÔ6„Æ„>#,€ÌoŒfLcLJ 5/I¢‰cù”¥—c”Bò朆$á@°Š¡L‹A¾p«ÆL’®¨)à†ò"àdÄ`P #9×'}Ö4ëÏXh’ÛŽdY³66ªQÙÈÖJÛ5Ë˲ùëºï Z\ev}ÉR|’<ûC4«}}({Tçr¶â8ûútœ”´ìå{¬žÿ…¯*ÛaŸŠëÍöã$q¦!A«òðé…fŽc´çßw„Œäž¬Ù¡À~åæK÷憕Å72‹9` FÉ9™gÒ;Psqêç ÎÞ>dþ5ƽº1NmöÕêøeN‹2|â,Q³˜d!Ï9żœul#9?§/{¹ä¶Ú(ìZ¥º 6}’‡z-´z¼¶è(aãfžÖ3ðÔ¯/aOR, ²]Ѹzdp\L“xÛǘž#]¼î&Ýçhó»Ýq­ê`׿aäêÏïT¹mjmÈ™ÖʺÕØQ aÓ>Ü[;q|wèÃ#9ÞÝÏÇfqª œoy(sOˆÝö-›õCêKl&HÊÂ0A";v“ 8Y)_&`É/a!œõ ·ÕzpÓH[áÆàšGÁ¨ƒÁ•ÀNÿ«;hð‚ú*rYz9 Dw¢cTX\¾ª›ko¢fŠãsÓÛŠHZ¸Øوɸ%g“Ù­^°sΡCKÕ±œ¨âRSÉW|Dzè œ2ÀNN½Î$¶êïšñõ»¤ñ©km½O°®#@iÃ…g/!­‚kT”AE`©A…’ÐKcÆq#VÑ‹«Xw#3eÑïÅ´·ï¿‘ dë̇~õƒ“½«r†#árHQkO$±((ŒG8û~$â\aEA¦ôGî#3i–ƒÆÙ•ª%$MaÓMnªVT?¾grˆe!³¾ÉHÜ·Ê ‡f7?ؼ¾åDä‹Ÿ·ß’Ù0CiŒ‰4£ÄÞNÒh,ˆ¬ƒF™Jf¦$= ‹#9¦‘€ÚÉ(dY$èëE„4'ÖFÁ°5’‘F:Ep[ÌÙA7PÃÇ’è\ÔˆmZPŒ9e®0 4B0\8ÇbÔÚáJEÚ¥º4¬Y#90š7É™iRa¨2Õ¡·#º„¦U#9ˆÇ¦a¢AŠÈ` ZiI›.Ö|tAªr’‡"‚ÝŠ›CÓ¦ÊzaS ¥æ±G©!3¹E«ØcsÆ‹VÞý4é%7~յ™O*Ò1Â!úÍaŒ¦¾Æ),j]‘ÚÜÚ™áÁîj@”tG=*‘µ0œèà¢J¦v²(±db)4d“”LôTEæë.±ä£»Ôoʈ7‘±ÍˆWPs";ÕàO§~pßÎõ·èü^ýls˜ó¨I :¤êìòñ3B‰¬…X4p†‹#µÌ>.²{OŽÛioﶔÁÏŽØpº:;ÎPRBHÛÞǺäG¶_²;¨ñxÔugÞœÄìI%àI:ãÇÃc¼b}Ç‹Ï SÀ#¬÷4RÂÆ nŒ7Dâg)e™Ë´bóñ­OIéÅ,£;Í`ƒ®ÆÈÊrŸKcE ”››Ä‘ôÁß}Ó”ÙÌ'ÒÙ4O”ÐÝ{uŽ|‘Vr¸·Ó¶a<6})Õnø]FŸ~Îcnz÷_³lV>ûðk¸½l}ó«1ÝâS’zæRÌB¸ë>ä5åâö~¦Å£a!æaåÎÎN#7Q7UÃÿM{vÓi£Ì“0À8h3´ãPê{.èØËË2°‰?Í®£Aû›Ûx}ƒÞc#e˜”ÂûšJ8ØCZ —æðf‘\¤LÍŠ<ùòu²áb'˜uŸ®ò—¶Ï³~µ·FnX¬Ýô×aæL¬ãV©2D‘ݬ±®RJÖ²}Üž™ÏèÁÁž:×Ú}9lÚ5-‚ä„Fý—Fm¹reZHŒQB³U QC³²­á¬¹§‘6ÐÁªPžçD¹KQ#9rÑËÆôÈ"„Û¡¶#9n”"R!ž¥”9UëÂc–‘¼9dIÉ·Ø;p ’è„#3Åq-p5…ˆðQq—`{m¥]ÊÙȹ¤Ë¡ÅêAIF@Ã-Í­tÚHµÍºV·”ÐÅ"4äÐÑf!Á°Æ1’ZYiOe#}cVR/™p`ØkÉkòÍIßKCxwÚ2·†@Ê0º-¦FÛ,Ó-k¢eõã¶q©¿âÂAôž Ë׬AOÌ"”‚œ}E¾ŸÍȼ»•sˬ?!z­ç÷ËxÞîàƒ|#FG/¾ ºÏ•òêåÞŽha¤aÎ¥ÙŒ”8j¢æ‰‰ ƒJ-ß·`ýãôŽ¨ö³}ª¶«˜õ3áðWt4>b‰"ÒÀ™ÐyÇñãòñ»ò6¥J‚>ñó{XY·©„HÓ5 û-TÝûÔx“ãAéÞ«šNd1HVþè¢èTŸD)£‡wVŸo³’Öò/%%ñÔƒjE#9"(Ñ>¤Í‰*ÅX(ÀÈf×ņ>pr0„#3#9x^-6ÿ·#ÈOŠ¬’øϱ÷׊/äú7'‡Ó|œn‹†•Àî!O’(Á¤Æ,0¨ƒ#9DNd’I>ú¸5 _)Ÿ=7r¿Õã{6ô/ħȺˆ·,ª0Y$Íû;ãÍÝÙÄzEü€#9£²Ãçù[#3¤YdÅ"#*s¹m»§šê^~Ë8tô¿ôcž=½˜Û)uøR”¦¯ÍxŸ$vÃý˜°ó|Ü8ŸÑáùjøV¼oA´öÃã!”Gá¬0ÇÈÔ¬C€Ð‹T„y/rM#*ž]£…ïötE'ñηy*:’èºH©ò'Év3”y=¾àæÆÁÚ#Ö©gšz_ªè¦U•Q‹‹ªeÈÙA Å5íô?ãؽÝ¡ý¦£ûÿÕáÛõþg;Ww:o Å2yxvÿÀ¥b¼š9²-¦#9½Zª–¸¬•É?övÿV$8¡îÿÎL_ìµe“gãü¿³ÇOB#9lÙ­ ?sAd‘¿£ËÝuð±ãÚáÌúÎTz1ú“É·‡hˆ£h).£w—á_Îoãûjõ¿¿Þ»b,*[ž§kAÍ©,š$Äl©bQÆbhÓb¯Ù^ŽÛµk-Üë·K\¯ó–#3­÷)1é@ü<)Õ >$‰¡‹iúŽj#9aD#À¼‰  Ž_[~ÐIºüÖ¿Ÿù€ø½6yÃh6E)^«öqJ‡N a:i‚½i]=(ßÊóéòç²\ÐEÍŠ¢‰()%*A>wBö3^œkñåý:{覢‚².ï·ü(£1‡æñùg‘÷f×ã4çºk¯›Úeò­Œknµ·6Œw½ÀßçK?[&ˆ01Ñ*#Þ'&µø¾êöQ´Þ¥\Cmé$삈*nB¡TQ<¡øz²Nÿ®}zŸ‹—œ{lj£m6#”E³ ¢Q¶iؤ›ÙÔâf’¾g­~®žàyÝ0ÿrEéÂxXÊŸöÕÛM»¯ô™f—ɧRÿAýQ~ú”¦q£ï?¹Dº ¦´–ÁŒ4•©7šºV­Ÿæ×ks«#*ß™@ÛXsì,®G1ŸµíC1Øu£4T;D¦f>OÉâ$9uñ³m~ès}ÜuËÈX‘'„HL»œ¦Ù§WÁ®‘¯Gè×î¯ Jy;«è®7ßõ×'‹ó#àúåB†#90Àþë“Më#3±± œ'V¼àQ™kñ™=þøbÕ+} XÏŸ½IŠ…‡1GžÔOÁ’ˆýH°Ý6t¢°„¨~Ò‚ `‰?4¤ÐÛŸø¶:X~¼½¿4ôo|$_µ€ý$zÀì¶;>ÿ7Í󟛿ö«û!íï—Ñô}!ÞÎ¥òs¦Tõž˜h.6šôt#31•¿¬}óè»ÑDÒÏO9ëè]>›ãû…ô냗ퟘ‹uý |K¾³ÜE¤dSþfú¼„Óc¿6jðü´x”qýÿ¿_5È:ÀÙ…­Öñ ÅÀuG"y’3ɽŠÉ¶ávŸ=–ÖV~]wºËis¥};¤ž??ݪZ7öÜmK±¯§ç³YÓ'â ;‘—iØåîÿ&Îxð¹¶Ò6»øiÝz`bµ"ÞUL¬ÔáËÃÄô–òT[¬rÚÕ!ݾ•ËñåbŸÕ@S'ðŒ¨‘(«æFoZRÿ­,>ek#*l9h6 (#ÜŒÎX¸0bè3½áœõÕ#9´7éºË©Îw6º?æëƈeNêõÕêP\©»’Mé08–Žvñ%öj¾»ü“'Äëà†CŸ¿‡-³ðf¨a?À¯õv›âzÚý§å?QûOâ3á˜Ï¥c„'í ¡Gýp ¥PÎÔö[~ñ#*ÿ¨ÕT²aÀ² HÌùÒ½ço*ƒÉð “Ó¨#Æwñë™Ð 2 ¹˜”ÊaµÐ¸ÁQXÝ"¹|™ÿô×x‡Y¸—ß1”Rtl<£ËmŠãkÕcúda‰ýƒéþ(§5zÙYi},Pà¥W&=Lz‚þžÕùì¨{ÔÖ¬B@iæWáÀ+Ê€³’†X+MS´¦ƒ Ó?™¿§s¦µ‰Å'iö¤S{é‚´qAü<^Òe7r?ÑTj;¯þßðÆ‘“ô;l~`=v=iŒ(/òHþ¨yØ#*þì¤÷ï2´A¦1BDšáÚª}ºM=}ôªüd:Ìؼ¿8Éì“»³É½Ï)¡GAòÊhm´¨ ”r¯ã©€ÆêE:Y >ž^¾™"åð‚7|/ÂiæHsúúžßé$Å>ÓO½F;¹C$·ÛFðºâs¬ÉªTóµ¯#wuˆÐ4¿gôÀ‘$<ý•ÑÈ·„ËSÕ•ô>yΨpOù0‚eÜ¡X³ôflãø{/ÃAÐ!L‡›#9H¡¯Ž<Æ$Íh— W•`X’ …Ä€ÛÛå%Âo‹”¡t+~›þ³†ûCuLlA˜°š°á.O§w@ü¹Köè߇F¿ç¿ÃÃêõóX¿GÔo>³…û¹û#V ƒ³ÓÏí4oW…š6¥ŸªvÛo-¿W7@ó¨ü/ö4µ}ßVN ã´_é¥Fe/[5¿U˧}îö²/€Ÿ½göbßÊ_.ÿŒïº/×áùü{„¸oøÏ èèä¼Jp+Ùõc›dTJµ{nþŠüw÷µK‡œú¼Ý'–NwÏ|hó±Á‰·n~½C±Ûâ¾¹³¦Ïñjv;Wãº?Ç»g³F~ch¼;ÓŽôt|î;x0\ÅG0Ý×èv“N™¶Žo&™GãŠÛ—£!勇­IOÒžïç9üdÅ„>T€Ö|.ü_„W·[ºº=YôVtâd-àWê‚råó|^:Û1-RCÓÐÉó\¶Êîä[)çáôë˺#3t-Êö²³ÑcæÆ0²½Ãì€ÇW%ÕíÓùÍ®áÓŠráÏüçlc#35m_GD¹žªòíݪÜùqçW¿Å RË„ÓÅùzRù»åm¥û®ZõÇXñJ.‰6ŽoËGÁ°ë,×+lë‰jÞÀmæ‚Œi#3~,«Y‰ytqaõFÁÂ[-‡WÐ(˜ß~±]|‚s‹™³ ph<ȹΪ¹§õ{Ü÷¨ÕËfŒùuÉÜž®nLw[ãã͇—Iݬ›¥Ž÷yÈ—»ÙÂíW_Ý9oälwlÐÐñ¨aÎbÀòY7:î= WÌoã'Þ;9'ÏÑ­¬)2C¾ÿ'PÐO «°÷rªÿÚëMÜ=ŸGɵñçÈe 6ôÓ²’ïÛÀ6'8ëWy98ý6‘çôu/¿Åú#3žïO¤{]¥†|¤j®ükI#3&<¦\vÈcâß+µÇp#9¯±]øÛgæÓä×…:Ÿèð;Ö67Uìó±®­.tí·k½D}‘ÖÜf½Ï؆6eõ ?9µ@eh­èÆ™xþ¹8\»xã|{¡²râÒöŽ‘,«õy(ëüÛn²Š9¿‚‰”³å±,ø·Õó5tðËþcLEí¬ßù¾^äó/wÆTÒì.ýZÛfƒ«(î¬ýQ?¼+ :›ƒ½Só.ÆŽïxL?1–‘îœ&6jÊAËÕ°_‡M?}Ú#QÎè;ϦûŸ—R-#*œHìmƒOÉôWíÈu0Ý®Kë[GÍ·C¾gÏóâüzzœÚ#ñŠˆÕ£’¿+¾#3ôp8ÎX€O%ðjycOú~X8îü3·ô hdTÇ•òöâxÄ_Íä—WÝò-íûmûôàŸIýçèúàÅÚ{´mßeû¢™‡#9ö?üº=ž«,·žâT}¾?§tÿ/ÜRwz¿W^±¯Ë/;iiwùÛøþ[Z›ÿ‡¿÷’ƒà#9(FAs‚¡¡(]Ÿ«¥ážƒõN§²ýÞnðÉ$žæE#3ä Æ®H#*õâÝÏDh³¯¨D û­æaxˆ#9/2H‡vTgÝ®°Ü6Ÿjí|þ?ªÏ²jáø{B~ÿê³êípÌoý5ý8ôjµ}^ÿ£íÄýbÖfÙâë·eèžÇì;ÿ";/ÔàD©>Z´.­f«ùüæ¤.½œ¿’÷"w:zìpþ|tw¾}]?·]û»·äáøAÖIaQO^‰aP¦gyT¬¾zÆ«íQƒ’ùëñŽª¨i Ñ0&¤‚qu^Mv`LW•Ð NÑä˜>t"“:Êî•ÌêÁLDÖ½9rkq¼fî_uÅîÏ<)Ów?#®€iPÇj‘ÖÌ—×lpzñ@¢]|Ÿ‡%èU3壈³zñv$\=S3$°!ÔKÜ£”tâZÀˆ‡Ú›¿.:wwHyi«çàˆÓú¸~‘‡·»T9#*ì&ƒ¿ïS„nK]=ø¿#*ÐE{w‘Ë0kÆT­‰0è’ò•qN\Ž¹ö#9‘N—Ï•d³±l‘Z‘*;}Œîg8z =ªô š.'ƒwr×E²kXß—˜¡©ÄÿuwƱq•ã·gÞã_§i©2áÈN½y±õŸqOd] Ó|ÎÃQ¨Z6šÕÛU5ÂÈ´† PàwV¥£MäŸÃÖñ§îM4·D,¤“À=–Ü‚êÔƒ!ž ðEÛÅ–›€%Ž:'ˆ«†=…ߧÞ*ñÈ¢a¤|îò=Ø^û}Áé˜äA );ˆ¥êœä$öo#9#*ñÞSqÜuŠº.e½Áî¹>0o5ïùhâŒ5éFïGÔÊúŒd(ôùÆ~Brøí¯KþÔáÈ5Ž¿m¢ÃH¢zô xî†Ý+dWkwY}L,#3_AÛûqyœæQôG×N‘ê+VÚ•ýªþ½~×# QG^ VýViæÑÛl¯®ªÿWaÙÎ_«ô4©ìŽ}°ÝTÕ¿U*[‰çÐL™ŸÞXùpfËyë|\ìýßO q÷*aâó€Ž)‡(½OŠgIý^m­‡”ò;Ëϵv‡<¯ëäô¶ø¯Íšmk¹/Óç¿Í(ž z”Å$›_GúñCèÃ¥ó±¤í'¶1¸AöZû¨<–99ÿ;«g§,dïñ~^º#3¡€o#*3A¾KÔöcÐÄ’­ˆÇaü¶Í*?—îdªS—!‰/Fûñ¨ƒÙ%<£äùý#¾õŒ2#*ÕË—´ÆÂøëoŒçþ?7ÐFÑçdùÑÊû\?ÈZ,̹‘µ,0“!1–#3AÈ‘Fdû|ê+Zƒ#3*ƒmŠ‘Äàš”T¢Mۢǒ¨H*«’†–‚Éd.›ŸÞÒî,†f®îSVe­HžÜÁ0Â%iŠ[M`ƒ‘cXÃL¦ Õ‘447B‘K#3X­‚++#‘Œp„ù¹Ñ¼8¦ …`²f!‘IUDßóÌÓ|уa ©É#ohµW}URŽ#3§XŸ×ú/u½ò}??îç]›ga((>ß·´~KÄ«;Ïî7­@w6ëcý»[ã‚ÐÖàæ\xV³3·={-!aÜlar(ÆÒe„aŒÁã<õ?oðMçäþ,ûC 3¨C½ÞyB¢šVÑ1©#£ ¨šÌ]´-&õ2#3‹#9”ª$ÈÙjÔ&ØÓlÂÒITíÈ&Ð$Ñfß?“jéû´¦n•ßF?—+Ö†½*iôOŽ½“ê8`Èßݯ*áœsx¸k§a¶ÝRÊsÊÝ•ÙŸ.û<ݯþJì§/²ºµ~ݾ­‚^AçU³óýÞ|à^:†?·ŸŸ—^ÿ´wÁ7‰âŸ§øÞûs³èÃòÊGû<Ð"à!«VÇ}·çöé1‹ðöyÚv[bͯ;-³š{c póɶ?XÔñâ´8\Q†Ž"ÏCbA$I>§}¥ØØà==ÞÿËò_·nÝZýž"Œ@µ!W”¶ñÇ‘À&ƒUSo¿‹€­§W¯œS¾pßÑ×”:p^°“¯öÕßÜäqsœÏrºNk Cξ›¡Ëüºñ TØ¥ºïþÆ÷~Ž­ž]¿ÆÝœšîä&Ÿ‚&ü¬ý³ý{æ-’È …ý±}¡oó„@ v,£$¬!û~СéßôiÀþx§„|¸¿§ÕÓlbhͯ#¹ÞµˆŸç9GÐ/Ëè^Q®B/¨DàíâèpT©n›˜tÇÍëÄôUQ…?Ü£•J¢¨Í{ xý¶_³ÄôÎJ%Ù°c^¿ÌFV²cnF„z;:fÛÅÕþ[ŽHŠÌ\—áS]îy$Ú$%îéÙ³W½y9#…‹×3#*îÌù„FÑ?³¯®wü¿*HĪŒÀ('بbŠ¨Uìߎ±¦Ú¤ld„q",CQ/äb¶?³.›Í´KË£±HÈ7bŽ²´ª¾>§Ù/åóeòùl÷õŽ¿ÑìñºaW †TîîøÃÌñ#*v,˜ 0X°F3×®,=I’"¹Že_²ŠÐ'ç639f4Ɔ%¡ÂFÒàÔ˜Þ*G">i0Õ-³#3ÍT)8#9æX "Ôú)¦=eöÑVƈSƒ#JR0Îi§IpE30ËB«¹j412ŠÔX]Æk¥¥æ^ÜŒMu–åCÝ7ˆÌy#9‹FC·Ñ¢´bç~¼£fÛɸ«¥#3ŸXÙ†´ÔkV#9>Å©ÍÛœcX1ÈHÉٮϔs·ÄQª´7Φßa­2¹ fVÊZÇK"d:Ù\lƒR"H(›…hå`a¢¦Ñˆ0å”#3³¼6‡±hìfÔ‡V"ô†èp˜ÛIÖÐë¶X6 ‡jnÁ˜ ´[2í¥LQÇŒ”àþ»L4Øú`Æ̼ÑBªÅa†°%*QT*thÈÉ. Dš­‰>…«‡át:w¤Ã(™s‚GHO#‚ƒÄ!ï?OÜ~Œdþ¸*5#*!#9* Û×vîngŇxë«Æ>øÅÍ5$3¿iëýÞ¦ˆ3#3Œx³l‚eç1~«>³)ºÁªOÖd¡Í#3‹qþo”>;ÃæÖ_·{éÓ·Læžž:†fž`'Ô|c¦yíÕͯїJt‚u‚€Øà´k¨¼ÖÍÂ'Ãq""v½š#3†œhW¬Q1ÃÇ#38ÍHÆFÑÜßSX®«ž`VåqX„ (G‘I–HÇZb9B²*Á˜”k@W³¾ö¡n´÷Fýw¤cx˜ÈLìköÀßê÷òÊ>V惩çuOôªõœÍaÓ|G…±¦?v eŸm‹NG´œŸŸìðc+2&tí:÷‡œ™ìÒƒ6CØ~$õém­`ÐõN¨ñN,݇Öò5±H_½Ù;­6ÞÕ}öÅ›0Ð ävo—ŒâÁUd:#T&ëŒm+;æh’jÅïw¥¸ÕuçO¥›IBåÙÛ€¹ã7¤Sú¹‡wvÔ¶ÞÔLíŒ|XÚ­a9À¹¸odM±í¢»ä׈M»™@o¦âf{y6ñ¬°±¾¼§7Û:XÄ;"Q@šteJfÈÅ PÕÂñ®ÕyŠAbÅ>U`ç5/<5«Ï~+¯ñÜÆ/Àã¹ÔþƒƒjµÓaXRRgaí1fáÍÆè8|K"ŸsmŒÓ™¶¡17Ô©K8T8‰«Ã~g‚uÅ¢,2ÑfqFB#5;ÚQäJ¸Áu#3Sƒ}ïÄyX•à6ã¼¥ÀL’ÃÎñ¶J'ª3{êÎÙÃlÀ¹ìáå2ÁE§;  A„Ħ™N·>Ôq°ƒL®®ÆüN˜QÞë¹Ñ zqyër…ë×}¯&íëÖï«È[È›±¤Øï·ƒRì'uª:öd½J®/;U]äʨ.g=±p„AðGÛ.÷O#9ì=z¨Ú-v>‘mðÎ/Ê·±j1`3»žœô45?åãIÓ¥R½öçÙ¬:&†šlû^å†4ü¼×Iåýp–9«öšÂ½ñá×4@ü̶Z˜†í3Œ+–/ üu]k]V–Ó°B| æ#3¡è[aí馜ÞB¸Ñ#í5êŒo(ˆ|¾óJ·}¢g89mA½ÿ‹¤êm£Ë&‹Rþ=à3×6ê߃‹®Tq“„ΠÆ.5Y¼œ#3q'm‘½ m{™•BÚöEÃ8iîd&™Õè¯!zºXm—™SL%ZWÐÖpüið—KˆW|¶úD0üýTTø9Äñaĉ9â…™XãNR™LÖè6áç¤<³§vë‚žIÞYÐô3LÆs& ƳqcjPîÓ9–Òhâê(ˆÁQb¬;ýµž½¸ómà<Äãõ>=ÚOn¦¹Û'«çÛi%0¨Ýf4Ù§Ô…&ÂM†ß-¶Zÿ͆Ì0ZÑ ñ¾Ê#9þ€…Ælû±ÀQÔm¥îÐü›#[ÈRE¡ïW³q‡‡&–छô{´tÆuñ£xC¶ƒjÛx^1KWÎ(–*R]\½ÆÂ|òŸ~?Á|b™e_6Ö fBŒñ-“”2 [`—x#9@³Â̲ÇW~‚¿Ïgú{8]›vî¼Èiÿ „úþrc¸{sâ#*¿Uó“>\Ù÷GÄW·73ùoŽ΋¬5Ý¥'ໄ˜‚$þ™Á„;áƒÜùdÕüðw9*=Ád‹*?¨Ñ½<†š#3F}aËÞè‹d#9ñÎÀ;?@Qƒ­MÈSTu‰ÇD»±ø5T?Ÿöžh;¹ð†^—OÄ~¸">Y"ådÚp|jjâm˜&« œKÜá90—›à䌧aW9w§1Îp‘Þ€w±øþÇ„±#OV¯³ÇqB¹¥±ŠÒ&Øzt…nyç²)IQ»%—arä(AFÓ«ç%º{î œ&Ž5„Uõ5×h£ñDò•pð+Pð±ÓbÁ×q–A„4:4sUo#«8î0Û%1RnLD¼6ÙÅÌ#*ýÝ1«3‘$TÆÉü#9º¬6=C»M_…0­Yi ˆdÙRÉÑ/ù¶6ùhñ¹Šó:øG!Fm¶ñ«à3EIåZ©èêÛ>,….ëï$õ0é¼QÓ~ûLÌ5ΰ¼Å‰0R)“0è#3TÛúdkáW¦"Bš_rƒäô.ÍëºwnÌçQ¸é:ã+ºˆ>ßH^ìe“&^`©D¦G%3¶`%x^~”4!6[×`2´ìºîYGQðE_tï&½ÀôÉI=§KÜ‚Í„rlÈd{“Ŭ_#3ÞÆ÷ Œ»„˜ ‡϶Ææ·ŸJíÒs³øY»SI#u£ê)ìÛÜFìPø¿Ø-§¼u“#*¼Ywr£G‘CMÍ<» Ô¤lÕѲ½Si¬“ûêzä+UéN-<†“ò´µÉñ:£ñç£Å.ztïG†)XñÞ Ù5÷ãOŠûºxClô(¤õl d6î×Ô¦™84I|œûï6x?‹íGêïðöw Åø'Ü´$õ¨ôZÙYãâDx38/,îè9ð\æO|2ݧXŽå“OÕ¶–“#9l(j§jÂwI7(ñR}2gVU†G¦ØsëÀðÍHZaÑhXy×® XyuçáÀkßOצŽ‹"ˆ!4²~kvͱÇùQ•3–Áôh¦øÖ¦#2°9ƒ4W=Ä(`™#3{R{¬²ê¡gh§—­žF¥ˆT©]R÷¢çäÇ=¢@Ö4Ý ®¹3 "äx`71–TJ#9ðM•Ð.J“¸¨%ì¤1U#9]QîÛ«ùnMF_”ìfFIoò,¬1ט-QØ‘”DVˆYCQvîØ Çs”!ì4Õ¸[€Ó#906Œ÷Gy·¾S„ 2TO‘çjanžk3]ñö2†4]æ ò+Ñü¸Na:n ôÂrýOWo$ØHªx¬‰W#9¢å’§×‡ùˆ¿K=ÌÔ}åÒ6nêN‰tL\ èªžm@£íŠÁF<ÞE#9n~¼æ6‚ÀÁQ {lô‚…;˜têt¥&Àìû”*´Òh¢²"Bj~˜Ö9½”Ïo=m HÕ f%FAÚa ¤9[ô⠘Šç,Ó?´®qšÞ_âCåüzdÏŒaŽk ½ßVÓt™a.à€Nµê-¡ië)ÀElÐÆÞ¾6‰GØ>|G]¡ÞihÔi ZóØÄœñÀ´ãÌx橯6mØÛe—HBs¹SAdŠ-˜ %lW9 +S8$g´ko;RZv¨|çáºOç:±æ4FÙ‰všßŽŠ(gµÙóCªÕ¼2N#ð¬½ìu¶ø¦tc«ÆÍÐÞt·†ìÖtš‰âd“År¥NHêºåòŽ:¥­ÑàãT»,¾WE"Å™r²Ž#5š¹fúWK])°±V2bÖÆ—8@Í%äô)ž¤zzjÉ=Ýý»v0 †2$ ©§4-™Y¨Và ÈúáœknƒHAàÒÐNƒñã$#3äåAÙ¹Ý-ë 0ñ-™õW)>Ûvƒm'†Îr‰‰„gç×bnË[@BåjåÞ¡Þf»u28Hé­YŒžÉ®1Ê6<©0D¨µÁnŽHÅR÷wÛ“ *fý¦6‚¢9ñSHq«Áà'Õ¿‰ïîO|À/,™áÜF INšÑæÁ–´Úš8xt(ô˜ÆM9­?†ÜÑhwgÎrÏÜDµ6°zl¶Ùòd#3x3µ®‹Þâòo±jÇqàæz.+fôiÜ_3s&pßt£s(µ/u“ãw;ëò~)º®áöH@¡Áå#3ÑSAÎæð‹‰.š´îábÖ¯BïÏfž#ÇÑŠ?Ù)ˆ2íÑÇû}cϧ”g¿j";¹N’Û^÷¡ÇrŒÞKÖU9BÃÎÏüeˆô»œáÝþ{ð¨ßoFþ3­­º Ó?6ç »Ô±E½³D”OéùÀR @}¥I¯Û¨´=ìÓ’"œG—hÜó÷3õDzÚoà©\Ít €‹Ò0¼yê"iÕfز­QƒfúG’¬ÔŽlE8Ÿ˜yBøêÆÚ…}¨Æe‡Éi¹ÁölíÄíJÙ{,0`vy ÝÚL$Gd]í·›. ÷…™=9ÃÞnúøS¦ðª‚Qá®óLºÝï Pù"”A#9r²¬R;¢Y‘¥¶æöøÚ¼³BMëC®¿¦×öà‡ýŠ"xã¦üÕ·,AºŽñ„M@W_‰iR X:èNôÐC_`ºº‡w¼EÊb.b¡Ü$µÚë¿ÝÝß‚DUËÂÍsY±-y‰ÂSBj—>¤W‹³»‰Ç{ѬUíõÎÛ¼γq%0ÄÀËq?XÞ= Áy^籇“ÐãDâÊg<{ûI8ÄwâD$ÐãÁöRÔø`‹©b3F×ÔÙý |ø÷~¡ñÜãÚÜ8ürsýþNÞŒ5 ‰ûáêj‡èýÓg×jÓU˜ëÆÚĨÔ&¯þT„G¥¦¸ÝªÊWç¥b\¬×*ÚRÆ }ŠÖÂγZÄjXæö–n·ÔЕ¹:q•p}›¢C#9¥ëF4ÓpP±Þñtßζ³¹´ÛTp«¨^ækFoÜ^*$µ»’rz¬žOl¶b,ÈpQ#9µ]†/lµà<»Db#3(-i¼\ÙrÉ¢«“ ‹E!E‰ûÞŽŽØàìŸ#9e!O,u¯ê#Tù±àú†ƒ†Qñ|d“·pmÅg°æÇFàéÌ=ø#9Û’§tWN8YI¸ Ï,3VUc‹BýVX±SϲÇ_¢É[7(ZK„¬Ë&›f»ÁÊ\·>éRŒïP%šÞaG¼Æ!Ñy0ƒ…³kA¼Ü³ …²øÕ5Š¡Ud¶Y͆«j0ÊY½÷X€8it-ÒÒ%‹Â0u«Eå”°\#µõƸ>IŠ]€Ùã«°\¸Œk£,âÓÍ!M¥ ý§OjC1#*¥å^å½ïBêrçpš`ô€¾£–å8£ïÞÑhÕeÒU•Ô Z\Y7AÓ˜5ºbì ¥hí"wB´‹ÜJ꽇™TnÊæ»L%hÊØBß<ç 0‹_{0W\âØ©åR)ñ%IéëDýZøó㱯ãá´çS>úu‚u}êVA2›Ý¢#*r †å³3‚¼Y%•…Ñ•’×Ñ_˜I&5òÚÓª67;=qêÖeÈE°3SO5µ""Ûä'£ìsj»^4¾ûãªÐM*’aFf66ëì`UÂÊ÷¾‹kùŽSÖZSjUm/Ð)ǃƒ5wµ™Æ6dÄéÆQu‹y߾믞ÝøÇwÃàü¾ wjs3é;g›&^H<êL>8“Vsë{qÇ•Ž*5úTöh_òtíÁöRÁ«Ž$=¼Âß{Ç>*,;N«ÚªxàœžïtMºò÷ÛÈZhQà#9êJ¦àå3º8#9cÕ)ÚÒ&Îì-bÆ æÖuimU–U!’”fCÖW%DsS™Â’Ò7ùãtš0BÌ‚Š }¯g¼ß佪‡uJa´C{v˜7_fyQÄ?šé½5óøo„„V“vÃ[Ü%`ÛIEØFœ¤qxp#ÃÌ´"‘Ö f“ñG^e”^Ó×.ÝßÛVÒ¨¬9Õ9ŸËÈ'ýÞœ+éœ?BËΟ +y›ª=ÏS§Åìt~8{óúµkº®ºu„œ¡ö9lP´éfDtƒÄ]£ƒQË#9MÆ¢ºw›ßÙn8G¿T"ôÎÝ8é‡9ÄÕKû²îÞZogˆ¼ÌõæfS÷pr³^8—ù®#3)–„ŒËµç/ºm,%X`ú)²ákç+)=ã) ÙØÎênz©²2Ðuy«Œ_ÔËr¸ƒ@(¹Èh8½_9cX¿y©1L6ðéšP¾»ÚϦ°Ùô¢ÃG·Áð«Žñª—ë—¨šR«xw]Xzð¦Î|b<p_‡8×Ù{¦@í‡[%ÃEù9°ë¤)t`5X¬U Ù¥Áâø*Ks¬sã6_ѽùr¼Å ‘&ö#9z7w<·97‘}p{”îîs}2os#9ÃOÚO'Ž-²ò›±;¿Žqœ`¨L½Øã«T™Û:–¤¢6m‹›èÐ9M"Ìe¥ï/ƒo9‰e5ZÏ|÷jUL$°äÝN°RcÂv¹.‚¼rŠÛ‹ÃôõµgSã”DM¤bå#9w4½X”ÞÂ#°¸wà ×CO6\ùÅ „°tì+~ÕŒï¹TtôÃæ"—ŒÅ†øEŽÏ43»NbnISÞ½Ù•‡]ñÑJÒ5ûHãejᆧ2uè·±Ò¼®‚wP0Äv‘¤óž#3eöYÕ„#9Q@ˆsû7wuiã)¦>(¶ÞX”ñ¯O3ò¶,#3q^#9þG7$ÆÇÏ»£fØ“{š¸[q>q ¶_m¡@#9üýk€õù#uʸ#*ͱRáÃþjôSÆÃ+•S•|౉Z!Ûø?îN¼Ç՜ް*Œ•Cyè”P5óPd ­‹À_)#9øœvËW¨Öc­ÕQ)}~’K°Á£Íü½û…´AF£JCøÎÔHíÑj¥H^emg ŽÍ”D¶×í#‘Ê…ê¸ÉhqÙX´&Þ&…8¯'[’RÈŽiò6Úᯀ¢º+ùþ‘Ûkå#97Ôm¨¿V¬Ä²•VSs9æî/›‹¨–¥]Ø õ°”ÝdÍ-·:fÁˆÃ«®Ë­ˆIØ S…Më¥Tr¦€‚\ûg¿()¡ÙºvÕâZ¶X/«Â4ñ™ú¸{’ÞÝsâOß‘xÂÞJ>oPÎœW£÷G›£çŒ¤ü¶4f\Ê2¿y§oñîÙ„å0„¯Îç=Çbû¿Ên×XHëƒ0=">·Õ„˜ß»ÉM=&©º³j–+ñƒ’§¹‚Ì«ëí¤à•è7¿áÊ}T]CÜí³¡šÛµéÜlÑm4ÀY£CàGQ…<ü]¨¼ƒ#9د`•væ /.—.N¾ø÷Av +™…ËMÎð¹×vU¬¿œÞõÐ(•R)T%ÅÆMÑ­D°Ý+ÞZ’€Á5¦¬þwØG;†H ‚Íî]V<ƒ¶8¾d±Ý¡tÂ<&››üÜÝ—ÆsdêYõ€† 3•Ë=ÒOå5KÄzRI–crª)ËÎüƒæ£Ÿœ+†c£o@ºÛkÅ]³,ö–bþR Œ¯¾×:eäIw¿›¦$¹É]]ãr%Y“Nvñ|åý°ìißã3#3:r·}_+Ë|¤O]ã¹Ïnw®ÆÒBDÀûq$Í ÖŸÎñŒ¹îκ)¦´4šš«5Ömù¶lm caÛ—3¨¬Öù9ÑiQ¥6åÌŒfv–#³¹|gÝ…Ôenº7§å¶ß#3§~¾/Æ66™íÓµœØ\mLÉÌí7Çàþ¢#…²–°°=÷£ƒoÆç½jŽˆñÄ-Ñ‹[¦ÔúDq¶`|Cÿ#9úvßèÿ<íîÛGN–YÓÎn¯êDø‹KŒüdÍNœbA'ÝðÏ1ê/g¦Ÿu$÷u&ÿ]ÑNýbågÍ5sªð$}fõ‰»v¸z1@}*÷<©½>:"öïèÛ!l¶èùï5Òh´hÈLÈÏ=j¸õ¼0#âû áM3‘é¼çË'º;F¹”Αßq7×ñG?Ä0r«ßb¿Aͼ/ÌÍ´÷ÆÒƒj1 .+íÞÂ?°ä¶ Zå3û±´tãΠyÛ1e7ÜÎ+‡‹0\6hÙâR°e;^‰oÕ$H#9®m€tS a Xuß=û‰  ã [°¿Rã‰Ù¡ë.x¦j.œÞåу§@¯ÓëÊõ)Ææȼrg´\SèÑ;–ó¥ Œ˜!´Âö‘#*’Ed¶™o€åp#9d ƒº™cêÎä9&Ý_·”xý±7œÍËy4¾ó3íx_#9s[cÏÍÈWdÄZ%KÌM~ïlÏÚs´#3Þ*I>(æ<à7º†mÐë„bØ÷¼#̶j=¯åÉßžnΦϧ%Aº7HG×>Ÿ,q=È1i¾PN»W—{öõz5J#*ÜÖÑk²sá5)"[ÏÏ]½ÁxXÌ:puîÝåŽ|®ãÈàÇ]½mÒGƒä‡·:¨õPéJõ„öjÞðL:m¨Of#¿…­SdKÜåБýnÐ-ÿKÀ/Kô˜æ™ÒÔh¸ò‘¥3‹·Êêq¸ìç~–ì,rãœxÒF†ŒØ_:ÅPN^pÇ<¶rM³!Ñ׈†Š>K˜=ÊlœFɇßpó%˜ê,ºt‰Fýn_¥\T Rôzà’üRHùrú¿¦ã˜â‹Êú>sãý=JòáÐCù±Ç;ôÔ#)Ü)à•ÞÚÆ)iíPêñæÅ]»z&¸•áBð0QnJ¸¶ ™y SשÛÎ{¶®÷—5OK™é”«ÔãËÓyjêðÞ¼à7éèÓ™ÑHb#9H+ÃÁŽ¼Ë‡›V¼»Æ>…;Nõ^TøuL鸘#*ÅŽ¹À/L ÞºhV±«Öƒw÷m¯EÀ(ÿ·—VÛïAÕá·,.ÂôÓÔ¨(€„ì:#*·IA¬EìŠZvµÄkøx>\‹Ø6pîPðA4‡Ymt·Ò#*žXYèU4Të¨i$´[–é½é·Ñƒ^œ½Ø><¾£ïÈZneižŠà…!nÿž÷U=½nâ¶4‡ù¯þJŠµNÛ/žáÖºc%R:­ñ3´)>íiÛJŽµL9Çô¬#9@îZ'e§8Wkuî9£öË­Üí|@Ô“Ä< â?ä¢(êt˜§y›:ªûaí±ø(.[4A•Ðd£ÛTß/Ã4Xøo ×s:Êþ¿mŽØHÆqpæÂ(kùçL›çÏmäþ‡É–/·õ¶ÝçHŠª‘I#* Å`o@ïqv©Ùg¸½nºÔžŒ&§ôß,Q)†ßwÈÚüsR³‹guvZ?‚y£#û©†ÍƒèðBW.¡ÏØ‚[ë¤Á|Êoú×ù½`ãF§‡ŽWå8B&ÞŒæ³÷âÿ7Õ̱c•¡!TiV³VìúßÞ¤TI$#3°JeBÖdªkýïôí7|áúóh\KÇðfñ‹æúÿo_}|–º|\éRD䜖Qê )o—“;µ‡k|ûf/ßõ>!g¼³ˆZ#©#*¨¼wêÞ9_¯G×maô…»‚3×m?ØÂßËÐÉø}`lØèX§¦ÆàLtèc¢¤L#3‰.ÅÚÒØ;›Õ‚EÂ%~ À ×БñA\%ö)w0ö½'vh TKˆaP-‡òÊä>YÉÄ‘?GîŽ «Ú¢£A×<‘l]r¥ZÐýöãG‘ˆaïhbD#9}s³ð¸„‰KŠmZ¬Tª³.5yÅÀ‚ÛÄ1Ýö¯á¯Ýù®g‚âU¡øö_x"ÔB7e•º_NÅëB¡(¶:l5GV§8¾ƒþ†—Gk¶Isà/ÐxÒá´ÓTÁк¯O0EËD…¥`ÙØ!¿ö8mñ¿wÉF$m®Àźq`u#3æ|g­¿Dî@6¢BÍŽÔ¡… ,†¿eNˆuCTÜý‰ø¡=‰”¦+¢èsü¿É|¦дÍF$é#3„‚’ƒ›Mì"·Ìw™#9Dhñ}[«½j I4*øÖyé/HÓ8†¶¦$÷*ããÇ•-³ºkvïõÍC›(`L$¼};(¦;6äGêΠJO~Ù ÷=~åƒÑ9ØïÌÊqý |‡·#3‚’#²=Eñuì˜%‘$YsˆÖ‡»›f>sß5¨cJíîí"ö&28Ž8N_¦II‰;(Šžq¨ºÍ¢‚¥ PB† Ÿ#3ꜤhÝXÚ–D#‹aéïÇLâðMJ®?U!ýÖ&Aiœmø ~_/Þ:mæ†o±»ý¤Í¯2½¡°!ÐÆÉ ªc­P‚É„Ñ(ë\øbÊCï£ú@ñqßµÂîœRºº©ê,-Æ :»#*fQ%Šêž=H‹Ó¶ëÏå¯>Å&µD.MuðÖÛ†K=¶°*5#*5Q5»Fs†  ˆÌ+­%ô-NAÖ‡s—ßíÁ+ú%:³Ç½ †À–Áîì˜\:nÛè/Š™ •ícÆ<¢Ô`IÛPxJe6äW«yÏN´€²‡@ä°º0ÁL#*2R!Ï6¨ J\Óxã¼åñ¾2@Ž‘;¯-3t \GÄvõø ì²J¬t‚+(l#-®é‚Ûäzº/0«ËÊt…|cŸëÐõ×òtâúE)ÅÎ×ñ©Ã°ðºùÍ'<@¶B[ØSÂnô-ø•\°N¦³y¹LýÒ‚Š¥¦<ÛóV› ·ãn!öž@‹Crp}Š˜Í= ÒBåT[Ç›¼èÊ'ìüíÎOµ½7Xç0Ífµ.'8¯õ³fY¸úwðm|Í!\ …ÌLí¢I¶ÉG;¢!Ä`K®¬Ï ãK#*²m¹0MÉhKˆs\Œhð.IvvÊOYD‹(ñ‘¦÷€àt_Ñ‚½“t{6ÍoÊЯÚSX!å~eÆ÷ðzT±³® ìK|×è鵟L$¨ûÇCn|à1ò}Œ¾?.WmTšß"Àîɘm pAóLÃdÇ)©ÌÜ?U·<…ßmºß¶Þh8,ûüûÍ?HêËT~Û(!eRòäwe×켨÷YÙ#3ÛþS{ŠTzÂçšòߠlj¯ˆ°†+ÜnK$Šô#|`Ù9`€_órBƒ€QÉ‹«bZ¡,e¸–Æõ®³ñw…œä’ öœôEŸ#9ä¿#3qnÇ'$ì[#*nK‘ Qp¼rñäP#¡j/»0¹”tng¢ÇÌëÑ_ 8/4öõ{ì¨[±â÷á§Ç%–&â’’ÑþdWw,/óm/ê©z9Nãõ‡#3¸ðæðvјtú±!¥KªÄÛgÛRi™­ê%¡ÿF*F¿Œe½Q$ÑRb(^‹PÄ,´¥ˆõG— ¡¬!.CÎ ¥Øõ‡½FÀvÖ0×w*æý)UpK8Œ0Sƒç{”I#3'Ê#*ûŽ±Ã³…Ö3P¼ÛÏÎÈòÚ¼¿änüi‰ðs™ý±VQÞ;ái©`)DÏ}13÷ëÙGÄyöûøMTçµmí#90)«™ò(ÓꮊörðëÆ’p 7`Ê™æï< !N*RøO‘t\l‘êвo‰R@õtÕƨS@ÞMc«}ûRô\×™-ænnëJ†A–B y;üäøžÞN˜ƒ\¿MøØ!ßÝí¨Êz¹ÙfÓ‡šd]±ÁzõœØt`ÆaZ<éáÃÕ#3XvzñŽÀˆ=ÛGϲzÌxvÃ×äY„QŃ‘ÎçmO¬AéFërÂP`\ª‹µn>ƒ¼báã]óm+K´Ãa#9QÁŒõíÅÅUPçæM‘Ö.·˜ÜCŽ’q±‚ä]Ðy³‡ºÑÎÔºh4<¬r  PB%3ç·”öx/ª¹lE‘©üS´øWÛU7-©øgl¾mªN•½Øh·ÈßÖàãM*Ø3™À”:Íì¶ÔÂÝ!½ì½uÁ¯‰è¤ÔCLÙv°HÊó1ºi¦Ëe¡7m‹ëýú ,åÈèóIFFdÂY­sœSW¥à;2#*‡ Ažlä#3Ac!j圉ÑuoS—lzõCw‘ÓA¿ìÈÌ¾Ë øôÙ˜F“;‚=ûG·V.Îæ˜ì*ï‘ ážÂ’†1Sf”ZH60¦Ó§n¿-Å|³¦0›¯¹3¸‹OnÇ ê_h¤Ý51¸P P`¢ÝW E‹ŒÈì‡]óJL#9J{ ™ª!]HµÀ†é~FËðPù¶%1¯#9#9æGÖðÐR9)³º ã]TÏÏ›í‹5I)þ ëEQÍ{fJl8‰ðá´ØMRa¹þ÷ùl¹þ)Z#þ*)€²#9·YÊ"‹Jkvîß¡;u¢î¬Å?‚QhJU`wøØú~jõ•SLö¥@6þïSÓ.¸¿WøPþ¸!÷tÿaQŠ ÎŠ¿¸úˆFIú=^ªËHLýT_ç³êØ‚ŸëÃüo4R{õ}'ÑÝ»O˜~ï‡a>túR|/?©êF¯K~U}#9ñjeûóY‡ì(€$ŒPê?Íø§¿›#*&>A@>¯c8ø¦äöí!„ËÒ|;­{Âõ.{Ú0ÑÕÆVA¶øíE‹>RÝ"íúŒw”´(¤ƒz‡ƒ¢ÖËýM€#_À¸å•0RøÜ:ò<Ý~oÙ´|ëFàhån•E n#3§,R, ˆò‰¯öàž´M]ö³,“„(¿ˆz#9صjvL 2±µUÏþHoO²'H¿Rçß»/YâCb xši@u(ež¥¥„Z€£}ˆì#9@3,†¨tˆY‡ÐÀÎwÄw£l·4gaØ–#* ­àE¥wBÀÅÚÝј—1RÌQ&öÈØå¾#9Ø!±¥%Œˆ) —eÊGE¸±t¤s)(#*Ê`™ŽÞVù¸ bˆˆ(jÝ5J4Þ/t±€Ì¶Yˆ;ˆQ‰aÉ ÙDÆÜ””µøš–j$ Ô$'ìÑTÎ*ÿZ-Štˆ{I>Ï2©ÿ;÷â=…+‡+ Š Æ¢Àª— ñó¹‰ñeüw¬oû´l8ÇƶO· Ðä´ ùá?|ÓZþ*ÅÛ¥.:,l0ÜE*¬•><«à=4Nz÷_ë~4ToÁ½*Å-b &Y3¢Bs‹¨dßÅSŸ]·–±ŠÎ£¼M!+½AO½Õ= ð{ý.l`Y}d•¦·#øpÎ@ 6¹ ü÷[t®|É›ÓOÛC»’ËĸaØH)6ƒ~-DÓCbl­/;%ÞrÐ,S½ÎnëÛK“GaH’6’å°kO†rÎæ²QCíÒäó«‘ûyùöð±`2¹%ee_Ñ%\/b0ïšêu yáV›´½RÎ*8 š´*©±¡²Âh)Ó¤§ \2NÏV0ÂRUTÕÈ÷Œº¨pdïCFjT2‡©ÿYÇ¥SäÓ‰8¥ž„:ÎÊèybæ§lÖå¶øì©¢º¾ùyZæ_Î×ULBgL¼†8|ðg´zQèZÓCì1Ìÿiá ž»5ë{Ù?0ÔúlfоáÜmJêóÊQ!#9ÙöåÓɸıÞXïhÉ¢¡•E $%3J–kLÍ)‹Æ^}7Ñè‘—%UP•U0ªNþŒüsp¸‘§kg½¹;£HÅrs,繶äè\LܲL tÉ·#9B×Î*Tq””HˆêÎЊ%õ–Ev{(`m½;ῲ÷ß·]‘SÔxÞ˜©¸È‰ ‰'7‰¹Ê†Îí{ÿÖÄ$Db#9rõõ60NI¨xbV}-H%¡7 Ð]¤©!²…;ÚhgèÞd.ô5òàïI¬Dq#*Éz9Q#9˜ªU#3³Tœ  ð®Ô€ê©FÛ:m£–¥‚Ú(o·qúúçt#9“MrûøœÎN@ïTâ•Â¤¶Iº/užÜwÇpÎ'r÷M “h0ùNÅ|äyóÃYžø†‘ §lÜ&U™gQ4üv#3ÿºÞº|<ÎÛÐbÏ…/^í7Jç:'Šz#äÖŒ‰Å%ˆy1C½5.P°1D¶Å­zƯ¼®»®k\ÕV–„–ÑKN¬–0†a% B™ S#*D RBH")y²ýip%Þs#9ÄI'4*‚0\ë:)6VP\·"m0ÈYÒ9ÍBf+¯M5#9%ªEJm²•2&cÍl##*†Ó9…Ê9äÚc鎉àv­dÀ5)¿k®ù¤ÈµÄ48Á‘’ƒNŸóqÔ[ù«R Ò¾›CÑž¯ŽKSê•* òžøxÜMg@l‚0U"2#9‹"Æ#*Èj;bZGªŠ.¢øÙ‚™«†S¿_CCyàÜO#׸Bá焨Ø"¸¹Ù™4Þ§ª«ƒU¶(ڌФŒ·¦*’RZøT)É:dq±¥zg}NÁ®v("[ÆS1C¥Ù›V+lá J9vÆ¥¬$Ô#9Ü2ª"5h ²*ÈdY¢‘©#±P#3D†Ÿ9º¢‚È*„7„ TBT‰ëÔ{ÝãóQ8gK÷'díê~‚#9ŒZB’xuÉ`TEXRâM®ÉFLDŠqƒÑ’Ì”l!àÍ^9(¸ˆ°5”KÏ Ï]õ­N»wßÊ“ÙÉŒc"‡’Œ¡fÌ& X L¤ß§ËDß_.5êO|ó°ŸA~'T8Œ%Nœú«~LYbPùו%¥ .’ÔÐ cù‡ÕëÝUXÌìê7óÚ!ÞuõVÄãbÛZƒÑÄ’H׸ƒmÅ Ô“c«JêxsÑ$Ä)Ö¬T··{^y Ï?m™U!R"Ó#9E‚-‰@ÁÓ‡u#3pe É"²(MÍPB0ÝÓÑ•ÄSºnòÕôÓ5’Àí" {q'P‡RLpî¦Rƒñ5Y$"(€ ØM瘧)lk–¥TŒ‡LZì’kŠtEMÕ^ y|Q(PUzŒV:×sµ$¹®®ê õÞMÇ]š®î”’ÄCs&^#U`:SQ}<x”ö{+\§H:-Û§Œ ÓÎ|,#3Ù)3ºiuï†Ì@Ùn÷³“èÖÓ›¦`œz]!ä2 èÚ«ɚ$”ÀiD몄 H‚EDíCiÄè¡Àô¸7ùÇr™& W+KYª£‹â"|¯v0uè?ÕG] méÐ%›3g`}öë;Ñi®SU®öcŒ“wY1–ÊIÂ3#3¬åÂtffÀÿGò rå6veϧäá8ðuN;ŽwG³Ž{¹Ðij¨T¬Ic`öû»y߶˜  ë¥Í¬`g¦*ºúó‰#y‰žŽâ¦¼‡»ìاÒƳ'Îë}µÆž!røD©Ÿ³µÍ:âºÄ64ºS½ãÉ©†§Ùþ¶úNæëŸeÉ·³+£Ždi˜Hgü€¦‚kÙ8në×µõÊË|“ÃkgmÀãrˆ*ô Q#34¸$EM#+ÞaéžxEʽ²sºHÜŽHã$l~¿›ƒ¶?i$=ipÑz³XÔÒÊzíqI^/¿çatº´1ótرäÂ^Ô‡»‘·2MnøoTwÚQ#3câæH×ÑîÀ¡CžÐý½ù™Â æœÏ S‡¿¯1¹Ù÷ÛOïmæÀê”UxÌøxêáËTž=.±A»yh`ä‚Û6L–b#3°ÓH4ÊÑë¹Q©5¤!²”&FSV’/™Ë»µÄÐÅNmš¹¾ošíGª)Þ³Fƒ$‘îˆD³ŒÅ¥Žà‰Ö¶#3¨)f»-;Td®×!zX@çV;£á¶±TÈï“*DñfÁÛ„ÞÒ”_,‰¡K{‰áÇ7Hpp‘Þ,#"‹8²ŠIJ‚;ÔYίp6(1®ÀèQ±6k¹ÂNÃ85_:®[ì„^°ã±öÂÞc[—;:~T„0~§:ûEr‚¾øMï¼±·G|¢å¿ëù¯uóPÓÊÑ·¼ö ˜9:ó–Y‰1-HSâ‚ØÆ{YmÖÄ:væû(_}Êå§erGɃ¨j)¡T}ó8äG­DI϶›„Xný ûîTÀä.Ò ši4ë“"¥jâO²Øþžî¯N2ÒïS]Aeá¸:âv “¾6È1Ð#‘†ƒEZg©Sq2GÂ¥P«[-À»²†$=4䠢Ŗ\fºÖÉÆŽ‹o ÄßN„ãðØšçȯÑþ›N>½¯Ãˆr{€Y¹ÚÕ:MJ‡…› "0c_•¬Iðä`Æ™qBÈ—üžwçGóæ¾Y!DÍ'"Há_#9Ú=1ï΄ª¨@=WœrÐÜu‚„ôE”=£©©´PÜ$¢:bð/vÙºÆÅ9#9$ƒ«œàMÂ7}¶4·!å¨Æ ]öbÃ=îÛ“—9±è3„V(>Q©aÐàÙAÁíŸU|€ÙZÆqË$8B¹T©¯D®7ßs†¾ëe5·®¶;#9h+ÏN¡Ø¦AVé)YërP›‚aP즊ë±!†ì!™Ã~K‰„3}¼aͦ,âkß^O ö'c×iÈìÞ¯ˆ" úˆrºð#9: g* tÄz Èe£É…=‡I#900dh=tš×ÊádÒ#´ˆi!dK°5C £ Ä&N…fÒß%ÝÚ¹¶DÑR<øÝyMQ¤ÆSc5¾¼õÚßÓmXQûT…D—ÓáÇCÇŠ3¥=uâ~8¼I ½Û£$:å#3@99<Ó@_¿•wº‹*ZÌÍC†Šm‡=mÖí.œý/”`³Ä´<÷#*òGÊ OM#9›r¡ê…NÞjKNúž+ ê zÓÝg7j©ùÚl+·¢’Æ*©é”kÙ1ïÆÏ…EäeP;áNã°-þØqÆuký>ªøÚ×ÞdlϷîºÌ‰’/¦¨ïØõçcìéyLä8ù` ä¿!‡ÜøÎÀ©³DC^+|˜JNi„.»(e„#9cö‡“ž·ÞZ:Å?•;øO“œ}“(y¤õ ,‚ÈdMä£8üôíèÇv¸ÍC]”!üÁáSŽŸó~ðL$ÀÇfÐÝð£úNë•|,æL‡ê¹E«RÊ‚?…ˆ0ø扩‚U­BZ [¦/cE|J«”Nâþ`hgDùXŸo#3¿ž§¡2É7=Ö_8Àìt ‡™Óc+ßЂØÇ$iΫ2;bb~˜Ü%áÙÇ,t[èAKäêœ^É<1åà æN”#3Lzs1B–cë8vŠîê:>fó)*”Êïsûcx–*Ù~ û-ûz 2dq#ꌖªLnðšú ¨ŠL4AOÃü?—ö÷må­×.ˆß·è´ÊSlóA?/ó¦°¼JAQ,†ªå…¹ÞºOêþÏV/ŽNânò* ^9ݳæÎZÉmΉaüÇc:RõˆÀÆÜžU,ï ¼õzáúý\æŽþɤ™#3Vå¿ñÿgÖB\ÿe»úx›o9á@Ç"\ë ä#*?·üžogçþïÛü#üeý¦V#3þßñc,J~N¶{KÏ13/Æ£ßWˆÌ7;˜šß_£}œïW¨õ1N¾ó·Õòì!tþUXúR"ƒ—~y¢7ú9ø| lêl0Ì™ˆ>¬(š”L£l—¶Æ=_/ÌÒœêÞ¦ð«úrL$<Á#9pÚÙÆ??¼$è}µP’ªT!É~@ãüÿ¯îÙþ=58ü­ªƒ¬@ïûïÊ_ÿ‡‘Ð’QS#9^T~ï¾AÞ_Cù½ú¦R²jË–ûðð>†/ˆÁ/í›t²m£í+׿äžt‘ÉAÛô¶€çùGÐ>°øSzGåö‹ :Ê ˆ)5Qø¬vÇ÷¹~¿ÒeMº=Æ.â9åUÎŒoÎéxÁŸº©7“¹¥#9ç1óŒG̳å÷%¯L_YÜÖºàn½ ³aâ"ÕtGe#*JggPí܉¬WliPƒæý}8AsÕºÇÓTý?çÿ¡Ý*ÀÈuöjâÆ“{°vüðV܇òKË`Zí]‹ÓŒ4Ý=ùA•ÄVÕ^#*‰”#9@Ö+xT[ÌG(m¼.G#9¶e½ÍXGªÊL®}Žæ£à?¹'l‘e˜èà˜GŸ+ƒiž«£ž‰#3(ÊÛ™ó[ê›KÞ @Ùª17´|}˜5øYi·¶À}#3{Ë!‰–:~?FÿjLdû$èÊPŠÁMh‚ß<‰~?Ñâ¯ý§›ëúïÛõ楹÷jýgG»Ò¿øïXñó²R¬“ïÔOSb{Øj(à-ÎHº¾pÞ/±Bæ>öLŠ ‘ò?1r“Oº‚„‹MYÕ?ä×áõkú﹪¯S}xq±h‰Ilz)TWe¹…“Ÿˆ¤œ?^ý v‹þ‘ºÿO-Þ?ð4è:ºžCcÖ/_3¨é_\õ}x5ð”“iDYä½ã£«OåæØ<:†­A1jyûûhöwz»¸£·j’ö¼Æ±q*­ÿ“i¢ªö˜«Î”â#ôgìô/+ca‘#*Qå4Õý•…¢eÓ#9Ò7Vy{øæ³>+Y‚•ývÜwêË~Šˆ×ï Oá÷÷‹ìê/Ý|#3«ƒ6ε{DäšÏ·Oáñ‚!L¡LDåÿ–#3"Ø1ˆ€7ëüß×ýŸIî*7Á,åæëÿ fƒZ|ó` 䢺µ`©¤¾Ùö)¢aìT>Í,«•ø$ü¬ÚWÛva†ÇÅÓ~¼p­„%q#?'ZØB?L-gõìÊÉB0ƒÜõfB†f:wãïœ*3¨Œ Ì96§·V¾çºòbßm#9Q«Œ²–š9ŒÞx±†¸œàŒ?|Ûÿ?ËämçŠS•P2 ôŒ…éÄg#³«”žNË©;q»Æá³\qòý`…˜½ŸT!GûsïÍêg9=6öïßrs€Ûw!<®촮º}}šP{*w'°z}Ã’1O’“Mrì «à‰ú€ä§âƒòÈ ï1«bj6 r/×°¾U¥³ÝA#9'TR 2ןºœ(¶± #3¥øT%æ6ã/=#3æÝ÷6æ‘×z4õÑÏíë%.‰â’ûópêëµZ¦še?ªÇŸÌk”¦ž7 –ÄPÃ1þ Ýíö ¤Ýöôv~nþ<.}h)6Ú|î6 È~]sòf7îwgDf0_Ù·GGOÉ?$a@‰¨€ W:¤™Û#*×™ùŽ¬Ó`ì¦|¾œ7lÃ’Ç_t$¹ý¤Àž«ElÆø-Oê²ÆDÙnÀ"FÞ_F7e•/ŽP#33öo´0¿ïÞßÏ€aêåu äøÐ}%&}/©#*÷«žyè£å}\%$P…¸>6~fÎBnL”W]ãÐ03ž©{agHuͬ_Çôýk„'û9°Àõ•* 1³Ó¾C{„Ú)URÉ0ЄàÊHÎ?S)—!#9v#•²>¦¡{–Òéß6¬?Ç9ç¥X«‘ý¦ý(‹U°{§¾_{·Ù>˜p© mVbAùC+>WÄ970¨Ì 3uùNˆúåpÏøoÇ“ÓW¾æÆÐWYRÕÐ:åouõàuî,xeõÃ\j¥ý´Uly`­øði?ég°Q›Ù¦ÿôfêåQ.à¹øì`ÒQø›A³à¡"㧛Ê×”A‡ŽÆ#*ªî/~5³–Ÿõ¼&Vée|´áð®·x¡4‰UÕ~½±Ù=½ðMÕ”TQàÊnÔÈ"åÛÙVrÑ¥2Í3Ýd®,1¸­Âkõ2À(¾W,º%ÒM°I±¯Túܳÿ&Ò¼vߣÍNO¢ƒ¹xjÄst® Ù·—!±~—d*õÞ6ËŠ bRùÖcc÷B¸XêôÞ}‡w­ó£¶|‘î¹3éµ×:—+9n}"‹=˜ßõ÷VcŠ.ówĸ·óŠ;t×v¹Õ=BXïêŒÒ²¢›ñwíåˆ#9xõ:ÍÊêµÝõ¯Ý–4h4ƒ »t˜gèæ„!.Èl3ü+Û>¸;htª®ï&ï®öõiªðÍb<¾Ô¦ñSåáV™Ôá¹\çÙ˜…µì/0íXÂÕK«:»=¾Ã}¥u«DJ|)#3j ÂBLóš°8@Cn=(QªZ+ËhÒ?>sÐôÇ ²!á¿g5çTæÁêíÖä4Ël<+ÇY´7”~¬åÜùïÞxó_Ç·¿!Ö!¢jŒïÙ0Ÿ½ª»êiÃýNj%”$¾ó¹»UÃÏ}Í]'m>5ÁñÛh¡5EÃT õ}±xe#9|¬:YÛçlŽ|×Q¨¦íÞOÂGI~èU4‘\7éÇû¼ ÓÅÌ؉©1¿kçä̾=9ˆ§‘elQÙÅ×èßnùãoÆÙðÇZu‡#9¡Dt’w}%㢑Œ¿ÆAæÕø[Á­s$!¨zlc{ÏBÏPôºåéØÊNOsùtŠŽš_O7“gá1Âfe.$A#*ŠF›YóÈKØð:®£ *±%£’°ä·²LÊúËàÌÊ®ÎDraöýsJë´9Q“÷k3çHÎs¾+4.H@¶Êlt‰Œ|Qh~ܺ"¦±X¶æ`G¯•s¼î½vC¬yW=—½ýJ í›ÛH ‡çË×ãôü#µrlí;Ó´#ÜñÅVS&ƒ¤L¸“oB¥$ WA#3¼¾ÕçW‚bC¹Â„°‹ïéÜ߸ºíŤ¯kƒ•`PÙ¬T­*ÊbýCÚ™ÇêJSáøÜÉ.;h¼·.¼1âV|~ø3nï™/'‚Ï峞N¯ ±fžA;aÆ\oÆzä6ç9*"}ò{Ý‚»ûª«ï_KÂ[ôò"-?{$èïp há8:1MÈÑgȹš3IQ^å&ìQì= ™ãL}tÜ~pDÁÄ;«Ú+¬™¾Õ£ˆ¨+ò¼#“k¯×n9ô»‰¤¹m¡_´G—¤ÅžC³Ã%‡àÍK–%»ç#9 5e/ÕÝÓÁÖ¸„©¤Bu•t3áõÁ]ú©Ã7Í3ÞvÎkãR*6‡Ö6–óžcºÒ#9£’¿W݆<øãî„o²í»†L±4_‡ÎaöˆÌ¬´±·Ö8”þgè?þ‹GQò¼^Cꉡý‘ùÿGd&—þô_p›Ï.Ö¸N¸¾»ƒØõ5d”æÑéskKGtÏöýìÑžahÁ¾£ãå—ß;ü¦u÷«iÍHB8U¸úÎBY½1ÂÆÿ¢=“#3øýÚâY‚’“×ã\;(Ð{XJJE!—aùެȜÕŠnØaJùÙOvõ£Ðøm|Ú}c £:Ìú9®ÞˆžE·¿Kã:Ôß2#3‡2ÒwYë1ˆØìà#9±´—#Ág'#¶‘×õsD$s“#9ª’'Ä*80v†ð/9Í[ñUµQAI)ƒt@›J!Ø<JÏãëP[†*å6JJ¸Ü}»•Î*¨6n#*1ç)b$ªç]Ç_.¢¥ôSü=ð^–òœÒmB¹çhå3¡¾çs—gÊdŸÆÑž+ ô`póë·ì9¤¸A°¸2ìÓïm¶¿¢„ßRâ.ù{Ò(õÿt2„E|éÆË«úplÚu¹íCSÓ[ßTTBÜâ®tN°d4YØqßµ‘¦:O7ÇBxÙ;àâ;mèwO?«šIã3iW(z®’#*Ì #*È‚´—V#™%üèäÃ<çïu‰³L?.ܾ{“³j”œ„ø°ôeä)CTìFªAÂtæ¤Dö3 óaàå4BZOb‰E&,V) i6øô²ÿG†µöæÇ¥óöC掹Ãüœû#3Ôðy‘a`pqæû0†ì »”of/ŒËäaFÓ(%îXCIþ3…"€ÿdm´6"d#*ÃàÒ¯xÆJ¢È—Š-È#ùàQÖ«Sëª/Ø!¥èQ¯Ü•êá™;¨¯ßA/É›V1#9{|Òµösù3°r¾1™H]p6Al—³»"¬WÂ},'f:¬tÍGEÁ™•pX‚×Ájiû™´÷ØÆÈÉÉææ0=?iX¶‚[ðØãy6bµØˆužÙëÿ^nßñêN{#9E…É̲)#*…‘ wW³¾áëó<#„ÏïãqOÍ#3;2T£FÚÿ'í™üSú=tÿÿ#S#2Õ•â§ÝðOeƒÕãV·„mñ ÂI;l”›Ÿe 8£ô¼YþÓ0œGN3¥Ù•Û5Âì‚zÈã£ñÙù»>Óú¶úëÙùË·%{‘C 1Z¼‚’°;µ?<äù~&€xÁ±ƒµ ÓéOñèMž½¿uºG¿Øå÷µñÏQù]Ëà½] :‡æŠyë6Oñ¸ÑöÔûó¢Ü¡LºÛ™Î$e¨‡é§Õ¸ž‹8;é'•x¤—Ò‹^˜ç³>ý:¼¾¯]¤˜ ÆÑmr„‰)ÐDd&È2³V ƒæþ^úUâqèyð<‹÷š£˜ #*XÃØ˖Ĩ(0ÙĹ#*QH4<@ô³£#*”Arppigúã2€C#*½* Ç°°e^'ep¾Bî{™¾H†äf#9Þy÷xs·_¬á^XÁ”7ͱ:) ±ðr ôKÜm44ÑEÆùÃù=4Ff¹kð[£>·;9”CT»~úr#*¶‰¸ž$×áÎÅ‚¤ÛűêàùÅ„{“›‚fßØ ÊêµñÝÜC嵺ärð‡SRT¨˜,_²ûÒå?‰æi®Þ{QCÀ±kÞ÷j¹,–êQ­~D+&ѱ2Á@•YÙÑ(ƒ×݆•l°pÎMð~QÝDp}¾þl Û.}ÎúÖ/„¨wå¸l“LÛ,®&¼TžCgÁ˜e;#8î®—ân$™c‰£ßЀùò:ƒ#*è×Ãjµ9jW$±ÂO²é™zD©e{í‘¢'ž æÛ6â­[Õ`™ôÊÁò×H`’“ w>ˆço-qxµY¶»w:þë‰{4Û£ëîàƒZ…‰I#*î T-o¥Ý[ÄŽ¥àÊÐb_îü™hàÉ\Ag^ýrм³WÉ¿¼òŒ–sÛ`ü5o:Ÿ¿SW'M6¶%¾ø*¥TzqP[#*im( Ôc3â… ôÖÀýʾ_‚l£·©%å0çPñnDŸ®rÉ nG2µÃìû—CÕ0sS1+mÊ—zH¶4+‚‡¬§q@)RH„c¦04e%#92’òG§+m±*7˜ywÌ\.1-æ£P+ ——b­#9Ÿ½å›ñ¾ÔùôE.ïúÀ–\ËHׇ§³#åÅ”éæ„Ò…ÏÀ~ħG=q×pµëRŽŒŽ¨9Ñ‚©[C7ôÞ{YS&ßKÄù-–Œ9ö|«ãip¹NžkœñvZ7s$ qäL4•ŠÌÌA8÷`iÞ`Ò pYGË#*ê_’"_E•ò†à„!&êß®›÷Ð]l¡ì0ÏDQˆ¹È5ÃÛzM‘jjJÁDö³´½œ·ËYˆ0;5E¢ø½†c[Úz2¾n¬"[èÎUÜÛÎ{ÚÒ꾯—€ï·N¼KÍÆ6ò[­ZÔÆtâ#OØß=qÖ€0(J0›Î T3u¿ÝdŒ¥¨R°U\6g¦w^ܾó¶é½çRJÓ²a[wÏ¥ûô„9ççÖJ|_qN;Ú׈a´ÕÙd¡ÁÎ| ÷†¾[qsF«¢Ù¦çå» æ%“›g›œ¦âT<.XCšñŒq/9Å–ZU…ìÁÌAD¹'<—Рï¥Å(Sn`ßÕsšq÷4táäGج®¢£U+šo‰]|CŒgmš;Œ…aµ´'O =NÜLÓ\þ­úW`쎄 ±Ÿî£e·§ÔAîñqä'´õŸP=JØΰåµÀ̇A½ü}ø²\wÃäiT{®ù &Ôª 2šä(Z‡j\Qç“ÑÉ&–~ 20ù«>ñœ>g™òœáš˜ÞǪO·îÖ,íE ]šp544|^Ä1»JNŽ¢zýÖÚÓ¶Ú\9*gÉá.—G®GíÕÊ"Þ”+Có³Áà&‡{sl±©ŸÕW«.éÇcù€˜¹zÉ‘y;g‰¿™‡n³´Š#´#3$‘Ì”™¤F}ù)§‡÷.uô,„SµDí,éúfXdç–/‹=\h6˜iãºÏCb®’m+PS2|žŠnŸáóŽIOd#*s­Å#*ƒ`ƒ´ã¸f/#L…¡¦ÛÚ¾ªÞ=[ªpy-QͶŠÄ{þ_NŽœl¥¿r 9g“¤Ç‹*¼ìyþa4 !ã5:rlQÍ!È3_$b>jÔc5À딯©l iSŽ§0ÔÌž{Ò¾º÷§—ϲý’KaXü#9òC–!6Ë—%€Ý´¤m€albš~O%ƒÈ(¶‹,`¤ózHèÖf¦HïEžùIÔ’d’KéÇF°,ùRáß$òõølÛxô ´+ø(„ÚHAȪ9Fý.g -~:òAËkÚщêð@"õ³€ä€óø‘Úê«/ 2« SX9lù˯ 1@Ý@\áÚö¸#*æÛ3Ê-É’3Ý0›,ñk¦Ð—¼&É Ÿd0ÝJD pÛÇc¼^9ç14 &È 4-šb»×ÄÓú6°0¯h7e *ÝÐéö¡‡¯=èêndë—Š—IÈ@ƒ\HIáÊÇ“G\·¤_ƒUÔ7eû\6Á"‚±/F˜m]»š$‰ æ-Ì·÷nü,ýÚ¼÷›¡ÙÐk#3žh™ðqÏ^Øóš\µAéµ[óñsòJ矟†xŒM¨#`ì²vrÚ¸J¶wa†“9®.ìí°¨"âY£VÑÞ#9Xþ•c¼ ;#9nŠ–2ÈZ#‘C1œ¥|l¼¤gªZ®ÕŽëÀ×õ?q†Ó+óÓ¹¤±gˆ“šÌÌ¢VK#9f¢TH`üÄÆ#**²Q"¢*ä[%}x4òoK§˜Ý¨îÕ÷Ž§Z®YcLõ‡>Ž][YÅÄ@2ŠT6ºHÅÛÔ8D¦&"ííÜ6†ä[f³˜_eâRkß ×÷a8‡OIFAjo<ïjI$ýpµgo4ÅóD­–˜‹ÅÀÞ(h#9$@¨¹!Ä0½†œu½Æ}yU`ÿ$QAKˆšæ –µp”Õyˆ§;Æ"("rK•,¸8<\Uƒ.¦ÏŠ‰?( QêýfëE“>0àÏpÉ)#9>ÛÅýÙ™lú§Äìiê5°—Ö‰c*×Ö¡vŠÂêÊPhË=q)ÏÑÔ‚:ŠçÍlÜy´ZóÇÙ5MàŒuª(]‹0õ†Q¡Úx0|ªÚƒ‘Ðõkð´ÐŒÀ \M%xÒ(*7e|ô?Ä2³%Û n!óèZït&ùeÛ† ]£µÚzE·×0°YlÕš{-¨œpýw†­Ð62 ÚÏé솰ëzà,‡y»#9àÖ³è¡rD$1aÒ Ê¿8¿ºtáˆð±`1ªt0†­;u9O>ÏO°=ý÷ã½àí·§2܇=Xܳ®—Àp­ö6sŸ¤ Š¶è‘h(@4 PÔDÁê­Tã~\SAÔ#pkÄ“™$S7Ii'±Õ‘’m½y!£lU9›I#3xôôÉ“É°‹ %FÝx rC¶–‹.(€BÆå"WK¥Ú|؇Ñk#3·-½@1#3FDtu¾Äm«^ë%¶BÓd‘OfBu9裆gÁóEòÝq¾põÑ}rò*AquÖÐŒêûé° ÷DA³ß¾ ¬?xóë0ç=”.‹ ûõT4!ó¾bSø3e2Úýxð:Øh2Q“³¦Lü‘Ù2)!ˆtœ2ù|WÅö&‰…€…ØŒ¯€ÙIZà6樹ÖÐ#3cžÖ{놑ѣ†Z2¦Z”\Öò L&º¬G³ûæÛc_ Û1ŠQÆ´çhÇ”8]¾ðTßmQáÝÚïC‡“4º v·Çª ™bߟ†:f±ÑFÏht¹íIðU¾XuÌk6_S EÜTy'˜ç=jx"ù¶Fdá-lÊÆôu7B:AiAmo B·`[mXÀDø÷¬àwä ÀNò‰1®8Ï Qn%«iÖÔ–Z‘P¸ 6ÐYA1â¹÷:Ä´pQr;nµw òF5ׯ[Ÿ¨`UÁE¨ø'D‚e¬ ºBq²3 Ž×¤ .ëåò"ðöúKûß°hŸ}Á¼ b?†Ž ö‹“@wÖvxØW¡^CªçÍ·£Tt~5L$VtùFXãËÆ0ÇúRA—8hÀ‡B§æš¤@“7ø¬íŠuËEsk‹áÙ_ž;vv#ÛTðÁøÃxË­ŸÇPóT,ÕlÊiœx†ÇÍ‘jhš—ùXýŸËØЇøóÒÕ׋]aà9#*ªëVo³çµàyœç°kN<#*}3ïæàÜ›BÐ#3NÙ¦à5äyŒ§^_¯WïwO…ý<’п¨|'ßãC°óË!žPþÐ.Þ00?‘¸~0´7µmt³ÂØMËýgR‡õÎCË”ìå…Rì#3»K7?°èú×èëçû)UU¿/ìãüßo¿,#*³u©ÚU(ñÌ02„œJW!ýȽëåöÿzéõz¼ñŸó×—ÈÛåþ)¡'õ¡ýaCü#9@°@ —ǬRõ ä•ùL’(b¤þfª¡Sü_å%Ô²€‡Ÿôj¯¾©„ŽÑx„v‰ˆÜ™0Mˆrb,#*Ãýv„’ã#3 ‡m gû™þ’Þ¬õ{»lq>øe‡ Ý¡a·øN÷M«pÿš Qûƒ70;ÑÌptö# ðêï8*›S46©p¡âG—1+×ÌÚ“ÙäˆàÓyã¸,VÝ…8§Ì3S:-p…ÄëîIÝ]µGõ7Ž}<á°ÇY.î©Nùÿ7?´< kÞòpSR§±{mËBä’Ä×Z«Õì‚É—øh©qÈP#*)X†p°’W”¡%;RŠ¨û‡¿û¦9¢›}¿oØWßðþ‚yu{˜62Ë•€ƒ•(£‡ßÕ¼tøƒ¼rÅü=9{±ßjÙÈú\éfõήa çP,‘*«d#9–.üÐÌÀ}fóñ5n‰})j#3lúŸlú zxйò¨ü£H[ŒíÐ>¤7×ð¿ó—ÛúÎ:µP#9.!f)K‰Ó]ÜrI¶‘ÃÔ,#*?[a¨ì¥‰ðE9 åÚxîLšà-Eb‹´ p2—÷Óa2u’“Öõ”†çÐMѲž\ä“ÏX‚ÿ3>ZTªãrÐø˜éû½ÌÏÊ°;äî9Út,x]íü7­–Ÿ&Ãpíܪ7ö)ÃÄ ØëQüy›pßcÛ.Œ HRÏ­¬TÁhDŒ@äÅ‚È#9D»—G@é ^òà»ÞKJQ $¼¶l„§Pu\ÈN•æk™#¥J±¶;K\̬˜ƒU\0pqlF‚Ыàaù zªI-´ð|R½¹ü41‡'õýh¢ÔþóÐÃ+ËqýŸxe‘ ú?Ùîô²‚ªÊré·£øιžÔë&‘h¼a5L3̳ÐÎƵRäfƒC¾ÅŸãμ`wð„òµäÞöj+çëëAÎ8ï?ñ¿ÓéÃÎ5\Ä®âH%Ü„·‹™BÓà’OÓ„v<‚?UºË¬ƒè¨d%*=1ðÿšíjð±X<<1†Ã>-õ˜ »&$Çóÿ3°"²H‡JKCçåÚ˜<))Xzr=ÿPÙUñ·ÑãŠj+òWùkvÚ9uϧàãLÑцר#9w®Ž3~k¶5k?AŽÁ§-¨#3Ð+dGÑÈŸO»wÍ8 ¸Ú#9'œÔä™{ä=(ŸtÐñO]@ÚõSñïûB ÑÖ¥ˆÄ}›Na””gã™|€ å0¶¤Wî%Cíøós©·gùʪBÞ·Gö5³ät‡ ýP–GgìªzJ‚J¦jÜ»ÞsqƒÀ!¹M‘6ÜTÌÿuÛ!¼ÛRå“—*þ·¦XõƬ—k×I€¥êvµ?SÝŽRËŽ‘lYñ‹Ù$°RUSºI$¯öįÙå»5°ÞÕtè‘Ä)±]ŽÞ8öŸ>/:gÐ^ ípì#  ïÃ#(m9Fk¤îÿ–›‡jY¶OJ! J‡¤@sGp#4ù=´»Æ<¾ Ö ÑëÔ}§ñŸØ:~ƒ…~zo÷¨þƒ1Oë8âÔI?aþ0“‘ß2ˆ)_ñôöí}Ô?3Äó3¢Ò0}æ¥Ç¿¸`cÚ¿²‡16ÿ¡u¶ƒL9×[Mo§hì#3ЬôÂlP+-"‘å®ïH–zz€X¨$¸mœ®›ÛY±Ì?_ò~ËûÿXoÔßÛGÝóèÇþÿ׿³¥i.°|/Ý©¡™µ‡È#1ˆ…¦¡´‚ÒõÈ#9¡Ü»Õk " …-”Rm(2d?ïÛc97ŒñÒôµUœ WÀ«lF‚˜ ƒ)k•Ýº&W¾f^%àøÏ%M•–›)5ÓŒ¾]:›Ù~E>GŒbtm=QIþ;öìvEð3+²\ ½/~JnҿƱfÇ©óG3Ó£})…íÞ< ’$‹ ¦˜±~¥tã7jSrˆ¢’™I‚‘•D’ÿÎëûl0YÛ÷¸úh&_¸>53Œ‡ê±ró¨ÇØØú¼/ó7Ø}~Â4ÜçùÿQ³ ÆýäVx×ßþΞkñ‰Ôx{Óð-$”ÉÝð÷í÷Îò}Åof÷…$‡Þyã(¯°@±[PèÜI'ˆ¥ OõXKb„ù€¢b€Ó Ü&Ùãæý£!|CG+#*kÀ;ºàɈÃúbü+‹?“o,#*ñûér"9„#*@#*l×é“•ÇîvòT/ó´G•oâ9Û zvaˆ$ ¦}ŸÃ‹b“鯺Õ'Ý‹À+ÜÞǹ#*lú©Ah‚¢_q¹Óc ÁíȸÙô?”OTßÁþÛö&ÀàëöIòG‰ÖWÚ6ÏÀ`X ,!×ôè›pÈ¡"Bé;sAcÏ¥Ìå½ó8僟uÂ,cN@x÷~×í;0†Ú§8†Öî‡ëÜíÛàŸ à!Ò#*ìí"¥HÕÑàçÇ´&S$£Qô•‚)@õpçÕ]Þ/Ì9;Ú0#3G¬Ó£pB¶qâO„ïäSi*~îAè…5´èéàè¯Î©ƒGÐüñ`«ãéÌû?>c÷²—öž&?6~¢È/œ'Ø¡½bÐ2ˆ˜ä@ wúƒ´#*½;ɸx,1/Z¢±+„h}Ž’'êÏ«=O?Æ ìûáðÚUö[’È0¦¨|Tºf!!ïÄd’Iò@¸€û‡è~#*;ÿ“`…X¬t@HíôþµJE$ü;NÈûO«€cq»¬BÓæõ~2ŽïcDëjþ:*4åF2r!k3/†vÌ|ȹ¥t© “ÏA<ÐD+Óøû¸#´\Œ+•~SßRV °:~ÐÓaÁ<3 ­¬|J¯àŒìï:˜É'ßHÐÁä¼CªÊŸ˜™À§L˜,O *Ä^²Ô9õíæÛrýC¡rˆÈºVõO¶ dάޣ¬;Dr:»ytN°ÜDÉ#*ÔÞmÜ=´ÃÃðKlzC@#9s)µT¢÷Sù:_ó?Ç÷@¯Ã³ÄÚÿ›Ÿ?»ÔéÔ1òÈ“2¨ û[#™¼üÁþÇþ†àÂ4DÐäŸÓ*(ò©([þûDpuweÎ(‚`i‚‹x­Ä`iÇ$n3…-PÀhxÜÀkú{}Þ÷é<Å÷¿5ÞOaøQå ®› )‡dhU§éFmÉï=È•ÊÉV·Ï¾ª­ªG(«˜(ÿÏâðW‰±;Ȇߔ(Tú#*¡ÉcôED7m6ýŸIó~¢ïžÕ÷h¾ìÆg#9\­vmPúÔñNƒï/Ã$\Â#*k´í¥;>æI!Gg"tÝ73׺k“+×íæzwXÂ^h•Ú—€ÈÈÀ§vß=ÆíÝsLÒÿ¨æ:@\ø,)BB…BÑËì"þ³3ê• kE´ #*À=äú@Ùû” ÛèoÖÁú2ô ±¾(©°*ð‹ìÓÌMãU^”UÕ UE{<÷¡¨ ó3ßakî`éþÙ­áaª]Ë—#Ô[ÖŒeb\y#IS9•¨#*6’L blÛE¸ !¨{ ûÑþ—#*DP}”›RBnÈÑFÑ“E‹av/eIƒoƈl2Í_Ñš>wÛ©JÑU5…;¢ÁT#3À íe$Švßrv§0ýQ)߼ئf¡C÷jX–J#9Nd܈0 ÷~“ïþ“ð;Ut U_ÞEûËrKóŸz'rÆÛ0+íÚ!ì­¿dBŒ5ƒñùz­|øuÆ¡³ £dÍ2Q_ò·Ê£nj½+›¤kmÒ*VVj»j-f),Sh•"22ß™Å-³¤=·ðÙ/öšpˆ2ÏÃÓ=§¤>³pJ#9 çuÓäÌð$ZôŸ")g4öú”aI«µü“0ØÀí3í7¿sÌÜ›´0nÂ#*iÐ…ˆM*¥ •@ÆaH@‘ P1#3%wtˆ` ¤q–J ˆ_J:°µ˜žJ^OD ;kÇ¡ÛÂÌ]!%FGQÆó·:y‹ÄpŽaÞ‹eizxÒ#3v8r&|öÑI9VȬáÚ˜çCÓiÅ!À£¬Òöî(ÝÛ­ãÐÒtôƒµÏByû'm¹Ûð¶×1·B‰¸È8l-¤*ƒG3n[p£sÕíü÷{L1Zó÷ž<4’æI"Ãt´¸Jb‚Š(øíNCz,ö„Ø=ÜGi@=ʼà•$®î~n#9œ–'SyÊ©ÑÝ[½Öû>œÛÜ÷Ô¨y¿(IÜ•³í…ZZyé“ Ô…¼ lŒ!kÄ£â[IVI$}þ&³£t38wìÖ¤(aÅÀÅ]C{ÙpKÂHQA³ETûÎÏ•¿YnõÑÓ’GaDsË'$/Ÿ_ó/6("Nà!ÇŒ‚C$i¬7ÈANÀ(OÜo»ãꢤ´ŒÞ›µG ;ô2F#IŽ¾ž¾q)cùh£¸$„#µ'ç‡Ì1GðUIðÞQÓÓ×2{+>äg_÷ÂGœº… âB0­ãðä JÈ78‡[,‘c$³Áž´0€‚[@•T•;;4±L‹P237ýñ?#`“Üÿ¸¢FcgÜÔÿŸ¸~ËI¨BŒøé¹?J^_šŽ9ÝVWØBÝyÔ&ä#9|äpˆûð%Þ¼û#* D˜®ô˜ôEð'æ«ÞÍS¬E¶n|uà¸dÅvÇè?'¹®‘Š”A‰J«EQòÆ3…Bƒ#9r£Âù|·TêWñ'Ъ ñÉX QXÁhM&ûØRd¼§ gpõ ­{¶R@„RêWõ!pýd>çuP|Ž¯´+¿¹ñêÒÝjš¦ÕZE)`²\\Ÿ áfÇ™¾\Ng1 ÓÈ@ÐÓøwvtû¡„éßÞnâ>A(#*ïÓ’½Áù\Ã%RØ·áøY.)S#*©žŠ=Ž§¦ŽŒ”ê ŸfïF£Ø§X{ÚKÖÃÇÃÎYçq’H£sP#3 òÙ"äDÚ#3®¯@o±KÕs…€ßp»"x›‰2ñ„ñ t—QU‡S1ƒC,(æëˆ>ë0é!@‘íg7?Њ9vx¢ãED èT­Ãáéo‰ôŽqVqô®‘¯j#3»@*¨J8iï!ÅT³}ÚQ#3òvöα¬SÆ‹ËB¥’Eì"Ã3ñ!ü~¿FÒüF‰Û³?×N‚ÀòC™‡bÃ'÷•w‘3áçŸ×¾xûôóö³à¯Ì×ì#9Ÿª¥CåöQyËk‚cW#÷¡±DþÇ?î”çâ~tÎj·‰3ƒÏü×û0lìë+ìãXÎ#*sáöª»gðÎñ¿¢7½5ã°moNÃö#K¿öÔ½:@ ÂÔ#*냛+)«BƒhîÀêbÕ¾†0|ÃuÁåîGX!Á(4Á$ƒH}XÑ#3Œx¸4…°éµTâXû{ÌŠ½ÅÞ<Ù€û¿7 ±ü`²òì($®î)C²×5Êé«û_¿Vߊ¿WA^€Þ½)Ôôê™wÕ˜3áÖ&`Ú*÷ ¾gYÉÙÏfmGÇöoÜŽÙ°lž¥ÖŽ‘ʱyå(œ¢Øé+ÑrYÁ6ª¦IþM ‰úQì+Ëq[¹ì‹ mbÝTÝ’'3q†Áµ¸ßQzØKÀ<ƒ­ ˆV#*ˆPhxrö–©×ÝâP(v_ì«áñÃ"€x@DDdÒ ŠÅ·Z+QA$>ÇÉèÙˆdþf¶×ˆ£þžuõåä¬H磚Øø&CLŠ4Ó33•U€Ò÷¥¨É4üÁïö>æ!P2üi±4Ol-hjÃqp¯~ïàÛûÏôWÓÝRÿ¦šp±¡ØnÞ a€Y° ééØ…`ú­^ùQF,2žOÁ®~ä@–îë/MÝç^E¿v wÏ †¬“;¯§×ñúGé‡Ñ+ÓkÎô?->Ê ¹š?B C ."‚Y ãìOZÁùŸˆlâqP¸?$a6¯ÛÝ¿èÂ<#¡3Ûþ±³€ýÞª5ïÚT$$ÜÀ¤®¿ ñP펣>A#ÕC…d6ã_â¿Yÿ1Ëi9ÆoÂŒN‡/Üyð¿cÊý]$‘""!–/¼äBIGãÕ€¯ëŸ½£c m€tý†µÃǯlnjqÓõU¤0[Ñ#3´3gùu¶ž¢PhM‰°¶*šmfJHF0"Á²Ô’ c$úN¿÷ý¸±Àò#*êçãP”ÐxSÙû°äÅUT 91º#õcõy’/èœ#ôO‰º‰TÍÔpÁœ²T¯Eh°Üî`Ù7 ñ7y·…ÚÉñÐ bO´¨AÄ¢2 ˆw·Ðñè#9—ûGÎ-‡/Л‰wtK$ˆÊù“¯ëáþÈ¡úIz+–»9ú JøUŽÚ¸}¨ñLÝåµsd1ûá#Îúdû úúü4vR»<ÿvŽÇ¼v| À$g£ÌÕÓõMŸ¬ÚJ…Gæî·ðcĹ 4U7Òî~˜|Ã){øØ[;z^%j‚ #9“ëÌ–á”ÉB±¤B¢O3ºË“§¬»‚)XK¥„Çu¶`uÒ€ÿÏm¿Ï #90ª"L `Q-òdУÀHŸ€÷·½_Á$DÖ¼·»#3{‚µ#3|€‰%°Tb7=gÀ›žõÞ„H2À¯×ß#*7¥f#9¦ÏƒÞ ‡Ù]#*h1´AêqÒ·÷¡÷(þþ¾’åõ竆žœñöÞ›vŒÏéУ¿7ã`­ß¯#—>è×K¬Úæ¦o9×LËdò”îñ’TŠ‹%–ŸÕW€Ja¢¥²xÉ ƒ¨0‰šn°' êLÇŸùÔŠéPҩТ°N„ƒ¤4¥LÅ1ƬTÓþ!6§õ|YØf¤!Gþ³3À&Ê‘ÖÌuâ -F9üA¡Š4ùê /Ós¬´XE똵#3n«Lî9±ñ6YÆô¢LÎLUø4‰=Œ´[`771¹ûí%XšÀòÀÒ,b#3ú°84b1Æ`T?*þ)¾Îñû¿oÙn·ȧ ‡³+æãSûÖãÕÖŸ·Pi°äz•F*¬¨¨ yÜ"þÙzU‰(æI:úç*•‚ýí?ÒÌæÙoìpM†ù“¶Ï˜BÜj)„Œ%~Á†H~óù•…’Ó¥T˜I† 5y35Ùß4ÌÅ-Òê¿(æ5ôÿ"BNs%ƒî=<@Kü9t<#3NÚ½+ 4UÜ#*’T[_ƒ›‚Ù€Uº7z?Wð©ôXˆ›²8DÅTB! sšßhòb0íw:üëÌ”py9Çwú»ñ1FѦPGCv‹v´J0žœF#À¡;C#½]ð[¡{ѼCµ“ΠA€@BˆÃÄ0¶ØBEߤ~â¤4KI#*¦(ÁOÓ‡ãZg2Dn«Ùôá~ÿ³;t0¿×†Äô{-¡Š5û¨³#-æý¨&œB¿ÈQ3—æ`»uF£ú½ì SP=2à>Û#*ƒfšœ}0ÈøCL§W=L3M ‡3x'áJ‚_cé kxŸ¬bhÍÑ2É2¾b÷á¯2m“|“€îèP;8i½||ùü?Ifþç5n#oOÈ8"º6 ~é/Á6n³I½ÑfØ- ÙÏ­}\ë–·C?¸ßÝÕ¿ä°™_i)„=‰®,z¡£2ç§v÷5]ªQ#3èÝ#33fgČȥ×Àó.Í£lÌ9œøRÉÉÚ‹2NJö³˜â¨Mƒ0Ù#*æA‰cAý%°¯&õàEؾ ÷ú×……8EbÊmˆ{¼u{¹¥#3ô~‰ô Ù Z<&*¢ÂƒùÝÄl(¼sŠR°€D± СþÀáÆv0øycá'ô»Ôu0•#*„À‡¾wüÿÕØäRš1ÓéT@…#*±"œ©ÎKÀgíûm×áØÙ=×åbŠ1ÑpzäïF¨ù &ú~ˇ€ú_G݃Þò‹â#3èñü7ÆbA"‰||SH4EÉej&9I_èÍœwד¥—Œâ÷k Q6ÚåPªËÖû$ƒáˆÝE!ã"Có`@èAŒEØIïˆvkò†ZØ­-ÂÀ±¢¦³úÍ°,Yoõ¹A¹Ü¢C¡ð­¹@ѱçš­œ”›w'7Á麗#3-tÆÌ3ê»-P™®¢;¨ #{óÒÀAÎΫêˆ7¹óñ?Ѓ:OIó ü·§£åkÔ?Üà.;á"Ç£àY8ƒKŒjŠ—#9vi>*‡Æ@Â$Zûï”\²wlž^Pv»#9´¨”XªÄŠ=T»¦t.‡ëºM%Âae¨”æ¶ñB”ìW¬Ø¼J÷@I•ì½Roz¡?„.Ø] ÊÜô8\à É¥cNï8Â$$ß’bÑ…Ýn™›ßèæÊÏÓm³-}x0üå/5)yk«#JyJ” Ñ×Êü6ËmÌp¹Ài7»8@#ø¸è L9ç½G3Ô?&Çõn#*vŸBô§Ø|«¶»½Qß¿Èû"›·`)ìèÄâý<×ÞŒŽï0„ÛnyHo] B!z R¨¦CÆ®M¤Qb²ïŠbÀøQ„\ð·9àÑMdavéŒl”àdŸ_24øæ„íaÉ#9@K#9ó_êd>ô„Œ`5òÔ L3YÆöH¡½†)܇J“6ýOöý1×ØýÝ=kœ…†Ëó×e8GÂnX¸Cßæã¢WQ|”cùW‰gçGQµI €³…ü|}3{ì1‡›BëÛŠ™3!nMÕ^öOÜÚCû˜+]áÚVO/]|–vIô†ôÌÈK¸znÒCuLÍqÃÌøíé룩ÆÙúeb%ôýPtã¡´KË·’"Ý©¢¡€äL(€êÆ:Ñe)IHºÈ…Xš˜#9~3Ù·^QXBô6T'<9‡¡…$7õDw2U"Â6·+ ªÉ^q‚õê蘫‚o×9Œ‹ZLÓÓq}p`ÖXÛÎd˜~Ø­2¯áÛGìŸ d61AÒX¢ÁóÌ€H õ±þ}žŸ÷ÆÕäðü¾}ÕýÕ¯A¼!žŸòù'ñÿ}qn\&—ŸÓaú" =WÿOåõuvhzv~ât—û,R}pWñ->ÔØwš~,·¾nqdÚʾ¢Åí‹×ƒýÆ<îþ¯ó¾±¸‡÷ž”Ô4²{RAËü1‘omUU‡ûsê`Â>c#3«»#*pÕÚn¦‚ r+fôІ»G‘¹5#9whÂ]¹¼àQi )1B#ðv§úl¼·I¹Ðê*Uõ™gbI/ƒ®$­‡C¦m ÀàyˆíÕÙºÛ‚¯ðv‡b˜;4.†€qØE£½éË‘8·ë–êàU^>¤ÝT]9w?òœ[‡QÞÞ£œBN) î$_Ý$ˆx—õƆì ãæÒf"°%–Å^y ©Ð¶6¯qóÞnWB½¾û˜mU‰½U e[ûRû4xmãÚio²}¤ó¹Œ©Hìßêóã·Gë$)ן‡;Y;/Õñë½Òܟ‡¯†¨C×ÎîÿÍ´ÝÏ«wÇÀ…„ëè”Z,?Ð^ëµÖZ6pÒ‹Y ØÔm ¸R´ÆÙ2Ô•H846˜0òLÄa…ÆZö‚Øþ?®¼€R#3T-Ò‚ë¥äȽWô?‹üŸj½¦Íe,i”Œ¶,_ÎÞ÷XAê±[;Ά›ÎEíJ¢Y?Oúéñ’ÊûPé„}P„QjîÛ³~˜@ñª)ÀÂÓ^A QÂØ#32‰Ëd #3.ÜmoÄhõ#3l[}Sl€ršƒUŠÂ±¹üåL}ƒMÞ1ˆ1£!ß÷ÚˆÐ}^k#Û§/p ˜Bn@r®ž À·äÀà38¶ÜÓÔp!Fø®c|‰&ö“ž$¸u#9B¹ÝiË]Þ}‡‹mäÎÈC kK&÷»Ž<¯K#9«_–wdŒ†€;Œî²dCYd6 Ät›»#9¼ŒHóKNÇ$#3+¿Æ‰‘KCbý+öÐÛ å0óUBF#/‰¦L„§ÁŒnOž²Æ¦§—8(uôé]õVª¹Vªå0§´ðLã£:݇rŠR†ÔÝky7wÛdã#—qåYŠêad$[gBÌ&ø¼æˆHܵÔäµËumÍá^†K¹±p §'ð:ÄÔŒÜå|KËJÙ[\¹87ß2pWyCÅ…2{V÷rþ,x=!¬éÕLËev˜¤´d#9È›#þ¬®Õêg 1 Ðh¼ƒªÞàÒØxW±ÌÜÂÂh6Ôpè¨}êªhÛ×ì÷l>­ï"̦vg¨É.fü°‚’°G›lãÓãçÇ»ßϿïbBíBÅd#„$Bˆoz%¥†÷çƒ×&¼nåk+,Ì{DµR©Ý¨é»Í¹„¼Ë›@Ξ×òR‡¤=¡ÀŽ§_P&iWÜd'ÓT`бð0¨3Xµ©¿Q²Æ ºªánPjƒt!¤,»yGP‰‚ü¶œãH¢ov9ì„v =np¤×x_#3›2Âqî<­*rÅMP÷ûçxÏK×æ$Ü—‰¼Þjõ@lUï;àÇ¥éIhÛ&Oƒ®åÌÆÃM նзP²°Ôla¥ªHrÏò1éNž!läÒzgêo^ϳn^Ì8AÞïs®C¹ßïX²BY" Ý·øª¬Ð³€r ^v<ÑJ'N9“yGstÚ'#*ºSlƒ* zœ0†ô»F8NùÌÒh<6E©gJäö•ŠhpšÎ'&0;ýæÆLò,¢¶FËMÍË>¾#\²¢›Ôtïîp–r2pxÎÊѳO6±sŠP)$ˆ S#*ÕiéKÖùÚFàð«5t¶õMÚ]î‘<#9 i5Às|8ŒHL=ð7ríb†‡4*H¬*‚¡€ôGòb&“—™+V]TV1‡@éŽÚhgLm¤»2ðØv½:ô‘ôéc°Ûë=lóªƒb*¶DËÕ׃ÓÖɧ$‡q˜ŽSE((‚ÖÝÑ?å!D9Í»‘QVŽey‰ÇX#­S¾ WÎì¨ùöœr>ª±zt-%ƒ´pÎe·r*¡ˆÈµ&#3ªx¥˜#30[°íòéôPbÒÙð'_œoÂ׊{0Ú#8ù¨î…<y(Ë#9'í #íè!Ô¿»O.ÖâFètË;sø ×D´[!¹“‘›Ú­·\&»œq½Ø1×¢âÒ¬*:@•py fï'6¶¦æ€Ý¶,B@"l†ŽÝ¬slyeË‘e‹›1°;‹é\±¹æ(÷œ BjqQ¥Eêr„×dÌÉÒãUt‰éå´6÷"èN’)@SIDV d!ž7o2GyDïÊhhÅ (B©Ûöþl<€çÔÜD8Fli¸™Adã#3È–$*⦲Ěk ÕùIÐèªL¡Ùì–c˜šƒÛcsCù˸Z24XID„L`lËغ­³&é÷ ×D p†þvî1wùãp‘Æܵµ¿C; à¸ìpl‘ðDzQ¾CF`£LÑtˆ¯úz1€jzl#;+R*‰GZœHÈF%JÕ9ž¹ dÊÊî öüª\äz…>öîCË#*R)Rx²Ð•w…ÛGYéôXx„Nfœ.Ë»$ßìˆ"Q©¹†ÃpAšêPR#T¦–R”zÈQcå CߧR¥ Lð‹´Òm$6Ç&ÃŒ5šÙ7#3E#’>aŒ3!ÄO‚¡¤ôуIŽ#3ɃÐóI!Ì´Öµz†—(Ûå±¼v^КX§NÂFámÎö%Q.Ì¥”:3‡ªqÚª ò5Ç߯Xà‡Üv`C·d #3ËîɃr¸ÄH‰AF#9ÄÆ@„s#3D.ò,‡¤é†C£›G¥ÌÉÜ#3°ÜU?º#9~Ïd•×†s7k &¯YУØö™ÑÛæEÍLJ[Hm^ÎÖR¶Wv‡#*° ÃÅÕ‚…\Ë”ÒÚ9ç©Q‡ÙʺÅE\SžèÓÖÏA†Ê—çM|^»Ò­³¡Ÿ^h´ÞÆ#3à˜"β„—æùý;йÍæÃV6¹ÛÊRWϵ묞›Å÷øjåÖžoHcHhbI#*íHnÐ Ë4‚štv†¡w‰Ÿ}°—&éeY$ÚR€r܉P@9c Ö†«–FÖ³0¢÷ÿ§R¥qALåÐ&´HDú]ÇØzŠ™|ÂKaI&)=éµ›gԸơœbÚþgÚe3$Ʊ™Ôþ0ÃÒ^ÿ{×’zx.#9ëœHïàæz‰Ïó¡ÿOºe˜áÿ\à!Ôµ’ÝÏ⽩•ª)š_¢mgÞ¿7ò6Ö¯¯¿6§´º”¢Ù›$£:Áþ˜«(;ûý^Câ=„ jÏPA‡—mŸÄ‹î:Ä#9t̘ë~Þ´>i Ä)‘)df%onê$ßÜ-º¦e*DN§¬å¿0”€TòãÇ&³™7Æ^gƪé2#3ky{`0É#9#ïÞ¬­Š¢³áOË/#*|‹¤ù9ÍPªd%LVpcÇ¿ŸXI‰Ø*(´µíWÞ’E€qø#þ¹ b%EƒQAiA|vР†oCБ|yÇMâu¾X+/ø¨å;É$#³S€õCª-Gƒ!"8’KÐ~±þb Á7­«”ÅS¬¥<ÌRÚ+ ŽŠ‚=OY #*†tQá("6=Ö¯d¦šì‹©dAØÔjAJØ`È=Ô†Ñ#3Å0" $ …AMw„#‰Qk¦ºwbî¦Fwjßäß“g"LÁ6GÛr±T"íe"1]ÚHÔ©¤†ÅC,‘Eˆ¼ 3¹&„ÉB•ƒH0.™$nhõ¶D[¡§gyÊR²2¤=š}6OÔ¤Ôâ'—UË»qæ*†'pç· «KABd)aA–{¾!PQ¤Ùp€P@j0@õa,ˆý”úá&l©ô¨àØõVÀ%¬Ju#*Ô#3%³Ó[(j dë _¾)[Ÿf•àp…\ßFG~‡GX#3ùÛ^ÁÕݲQü¯¤ Šã{Ì\ÀCÊ(°V H$ƒnxöÌÞ°#9«î5«–Š¥¦Y´©&Gïö†cÐG #*ñ‹"",‚#3¤¶em|®Z­Š¶+j»*±mÖ#9Ò­®îÖ«•Ñd¨Øb*,V ô•¿.·þ“æ†_YäÔm3¦"ªŠ“X@pÏ¢jû%q¸A´¤‡½¨•¶¹x¦VÖeªa”2áœ3ˆ Œˆ™ €Iˆ‡Ðr’H˜ àh©?Ì£ÑX16ײ"ô×±R’L[Õ×o©¶æõ7©®k±(ÝÝ ’òë¨×-ßÑóͼ\Ý1nqÖæé²VRºi9/ktøù<·Iê^ÑVˆ M#9ç¤1Ú‚ÑšÁ ø/žMhdëmöWáúímÉLžÉ’#3?¦R¶#*ç#3 —^‹Ò#9©hx¾aОü/ÓõOðäîûÊäÕÉ6Ó„ $(i.¨±§³ƒgqÎéÈ;Gž­1c-…ÈÙ=å¾g†nÍúI®™[ÛÐ|úåúùlõœúºÏn[·'[ÁàŨ!TI ·–"̵M>Üz‘47êèµÇù]º„ Ù3 [äjÖæ­Ëk}:ÏX”ÌÄ$BiõÛþŒÎ“JÙÿ½#×ñÇ1-Ü‚žÁ _°‘µä¥SŒQ?ýz\;úßÓ¸0\Z,“‹CÇ•sŒ(lÈd×Ra˜‡¹ÊÝVFÑ¢%*KM¹•"pt0SK#9K€°\¿S#*Gr!¿kÂî/@bÃKÑ»(½ý†°»òʸ³ªoåÇÀ¥Êo#3"Boôú#3mÖžóðò‰ôþ ¸ßÀÚä«ñ«Uƒ¼ã|‚Ip<ïk;xÚHK==í¬?Xjèõ@@#@B@Á|CǃߧG† €öñß²æiÍä´®M[q³ó“ü_͇‹mix΄æáÛG—’ãœÒ¬F#3 ÏéÌÄ°í»˜¦h;#w¨•S|­zÂ׉î4û=ÜÚ! U*¥¤îíú“¯’tMPJ;v§²×[.Ç—T>·¿Ôí| (#3Š |¤":ƒ 3p² 1"+ì¿X½•+ê);cL‘¶Àò#9ÎÀ×¥‡½‚^È%˜d‘&JSòa„4Cηð²î¡J‘AäÏ‹_—*…¦ñ#9c2F×dUÅT4ÒòöyoÊwM¿¸_F%S‰Q)Š@þ†[ 'H 㟒)ð*J‘¡ ûÐÛ@É'ÚŒFšÅE¶¶É¶£l˜6jÆ’l¢JŒ•ŠÍ¥ZÄÒ©-$ÕŠÓ+YQJfUi¶ÔÕ¬k2BE’9Ö ÕüžËý?ÏV½É}y‡¼‡bE#*`¢È #*söôÄ Þ521(H$.è_£mÌvÏ™»*› >—É‹š+w`EÂýæ@¡€ðÐØ늣¥D†,֦跤´#â#*¿‚;À#*—E1ã%`èÄe; “XO…'”¡Lü¦!Çû©Ð’E`Bg©6Àž˜—Ç‚‘!›t®l`6·4<ø¨%ŒÅ°`!3i„¾BY žËZf¢hi¢¯O\îà·Š ï&Ú’Šµ´2Õm„Õl³@:ðT¥@´#*7#*Aê̓¿e@Ä<ž¤ À|a+`Òn¸‹XÂ# ¤,Dÿ+ÒØÅ(’ÕQ„,ÁÄDø]N¨¾ïHôôÐg”Gd© %J‚ÄußƘ2€¨@!žñKñÆ©#*á²mlÓRm4‚«èÍ\¶(’ÔV®mÍnj¹LÔ)P”[3¨©-±ªc‘Eƒ}žÛö·Þw«ÞWµ}=é¶ Ô7.Þ4H*À‚È9€½ê j#Ñ}vœ__1ü·¿qêøâÛ()£„´†F\"où¨Y”'±ç Æz=Þ#*öáŠH#ú •ò›ÒöT÷ŸŸ¿ÿ‡ìû¿“õúæÿ-§²*'” "ÇÓ9q¢õ± #*,wú¬ñª/#9#3ÐÅVnÌ%ÌQ ²w4E[IñÒ„`Ï©Ô*!#*†áUL4>ØqÐô<<;¬ÒMØnÒT¡éØÐ]CCtÿ„E[À1ö°ÿ¦ŒÇ>º¨Ðnfú³ _Õúðbüýso¤ô¨°´“òCÍïÌ „¼fòõqWp4r‰âí!hÛ¬:ç„+ÉĹ×ßUûhEàÀØÀ˜4ÄP¨#¦\¯âooNg™ÇEQ4ìk´…:Aºð’õCŒPCýl¾Bjü6†Ã½Q¯rÜd#9dóŸÞ*[_ã0èÏGIÑ5Ø6D#9Ã#9R†&I¹.ØÉ??.ßì‡bwŸgÛë£É »ø”ý(‘#*ÈRi:’ƒ>fÌVΗð΃(a4BØ«+„Þys=D6»¬ù!y=á룘w/ö9jàè}ô<­Š>«¶³AØUÊ%NéyÛ5Öº5|~̦AUBMRmŸ­²#9B¡èšÐƒê?WêÔ<ôQ(h~ïÅ®~U᧠÷<ä59ìP~}%èÆ]\õw†G†~áSýÐßÛØrè§\dI¨|qx£´0@±sÆl@¥E-Àl.¦D§ Lû8”¸Œ}¤Â„.R¿g„AcYm·¦ï3c*¨M\1‹á¶4ÄePãW8t9¢”pªq¯èÍïgi‡=9¹¾cú¿ËEX·ØdGi6šc漆 ðЖð¬)3a@½d>"H¤‹ " #*€´ó²Xª´=£êE”ò~€]4åJkóâr¬Õ wõÿMï‘ ¼Ï࿇ðû+ß•ÕðnråÚq;%#*þÊ£íèxß̈Ⱦ`UJ%R#9ƒ„F9úÿkDp¦`'ü(ÎÊÅöè;7öå;}\ús…5Pg¡F!‰ KÍÕúRz$DŽŒcm‡ÛM߻՘f]À¸ÁÖ¬zý%å†sµÐ e#9(¢}¼®å¿% n(äãY­å;ÒÈ˘>Ài¡#*"u¬‚g"A  ,ÀGËÒäFÉJï,öÒßK)ûûr”KwåÁ/‘[è8‘ècs(Ÿ*òžžøçÊ Â·ÌwY‹Ûá½æ4>mçiðƒÌê&±Ž™üšo¥“àqÑszÖGƒÑÇKn:v®Ë§‡c¶¹åpçqF;jÌt,½åFÍCn¶ÉP›(å¸}³ÇHä'mO9º:mìÍG+•6#3×¥õ^Üñ댩 7<ã™ z àAå-ƒ‚únu³¯&ÙÚƒM«‡ 2ød|6ôw§fÆ#3ߥÛ›w3î‹Sµ™(ŽÕ»(R‘nˆå°å¬ÃZà-F‰… G¹FÐqÅÍå{xb¶jn—Q^ÁŽVaLù–{ýù›°ëÓyôã€,±2©å2c@€¸#3·öŽ ×·„˜õÂûÚs›º¨¢µ!Ü9gº€¨w”1ì°¨ï(R~²ÁnÒѶ5vèT¥z¯ÜßÝ«NˆåˆYRÈð«õàþÈO0çK°.Vr­sD!× ˆ#PÖr¾Ikgí,wêÿgV#*ᥳƲ:$Ó]ÆÃ6æÅ œãª ìØç¹ÈGCÐq$²ƒ&ç%:ò"ÕT©b‚0ÈvvxÏ«žù"g_¦¦Mh¤Yw^+"0F;4ÑY,ªn¨OmcÝîÜÇ¡êEJ=|7¸È‚!† HOS$ÔñΞÚô?G·§ncnÒìSQ1Ö0Uèt=ä²2X9M“³v…ö$'E—¯´:xì×3nÈÄ» aG9çÛ¬ˆò5Ô‘'"wÛ¥ð’§êGO¿šŸTé`€%wfÏ}ôeV ., ¸Üt2ð{6îˆÈ½z¯=Õ æp$ë÷d×fålNAááBtÑ+Wµ¡-ˆÂ’ ‚¡µÂ˪1D´­©.Õs²43d¶º\ÙG]]M›‘rhµ¥,ˆ½ÔŒR5 V* #9åˆ(ÈX–Ú"!%CK©åìX²"8\†Ê2ƤÝ´d,ƒi1X aò2@Ö3rH‘ئa5¦Qmi•_7™5÷ëpAçÈ£{#9låÔ˜Ò³µçÃSkîô†G¿xf?>µ÷zž[Á)ß{§¯5ëÖ‘e#*¨‰„(HªÆ0ˆ™E’–î»î¥„ £¦‚•²!@BHA¡ìœ ;çè.CågÞö§{ª» ‘üñUwl)iÑAaL“vV Òò3Ÿ›%²6vÕ áì°æ¶Sà¨P©Í#9g|uYVÙ}J)éüó¦F×nùâû’IEÝ—#3Shšš„LÕü›+f@ePOL8#Q-¶³{@ªÇS¸öé¦ÎÇ–àôAðR Í óÈñ’qð#3’:"«!†Ô±ªYTA`hˆr#9"ˆD‰R‘‘@„iÈåK–R@(4­‘,)RÃæ7i9«~S4€l`‡aôP#3ž3n¬N``q¸P£@¹ÌŒFD$‘jŠF ¹Ý=Ä/uÅŠÀe$v!•ñá“× —wT}¡{1‘ïêѲ˜&–¦wj&¸7=³’ܹÄàuÖkÜó`caFÿ™;1P ÇDÁE7?”šå­Þb‚Wë’m)c[bfÕUTùžÀÍì& ¤Š(2$$=Yì#9븸èÏOö«&_'¥"÷+j^€ô2X|ãN¼³˜Š60ÄÑón¡‚'z0 Ð3Ëg׋µàp„.;¡I¨(Dí¥”¹ãô¸—\uÓ³ë+¶¸B#3£ì|¾]Ëœ#ÒS}I“q!$Þ‹²„á¦ÎÕF1?^ú¶´“?«]pË YÔ¡¶²Žžç*’m¶ƒè§‹‡\›KGrìˆAjNP8öÁd#3ÎwE#*å…sO#3pÅO!¨j g#*ü·©Á„b:DàJnA¡,M IÑ(ÎóˆrK5PÙ¡BÃo%„èJNš‰R1F@ƒ$°K dN/ís{²½_Ì>4E[9îU hÀozã æ.#9½Š4!(Á.½Ef*¦¨ñ`¶¦û7—cq¶$C¤HÀd($lÖ\C#3#3vÑB˜˜QBÒÏA¥­enQlaÃÍÃl¤„Ö&匥¤¾dƒÆÄh!¬ ŒãF,¡#*€´Á$PchFŠÄ“r‚¤¬j0ÐÈb©ÅŸ^´Fˆ¿á†Ï×Ý»çëáòO†úT†œ"©S™ŠÒ£J!,xó  ó¹®û¹„'è>fèÊ…#3BmÊê%D¹óXxÝõ¢ºXØd›@žÖ DŽnË‘o¬^pÓoº‰àv€,‰"›2|6Ôÿ¶¯¶˜ws?æEêºd,å×}ŽGÛ4‡ ~I8ÙÆâZÁ²«ª›÷?9k¶$,‚šÞϳðùíó_w½†°kføvm6ê6ugLx×;|3X•1+3A²Ÿ7j`~þ¶yÄë·Œ8Љ‚ÒlQ@ª•DF—|=Ýçû ¶-@0CPzÅN´±°aÇÊä½Ö ‚]!æ åRÉÔoNÈ9€Ïh•#*{:fåJª¯IdNM.*Ê(¨¨ÄEcªªÁA'È™(Å&K)Ž`úõ6>¯µ›aETqÑ”êÁ„ Æ$Æ!™ uAr@–IlŒýL%4Û¼ígk«Å{]׉ëu7õ@fŒ®ƒ§[HÒ¤Æ0éÚ·Z‹¯jé*¼ë©"K_Ƶt–BbN~«ÀE ˜’@Æ©?Œ—˶Ùd0SdÌD6ÀRD‰!ÌêuåÙáäU4À¶¢ <#3Mœ¤,VŒ^"†"‘´ïs”F”ÓB~(ÁE‹\`<9²ýS…ñHJX«H΄„m°ÇÓFDñ´Ç÷Ǹ†˜–òj(vÆæ (b²ÊÐðÂlà!I²yT¯WÕ*©Ð†5š$ˆÄN€Ü:BX¢nÍ[Gj­àv³ÉR#AˆÆ†ùº“-²n±ç_8d¿A¶ÜmðYϧ9,ÀË$“£‡&јÅ\ˆ#9…m#9Žëçxa¥ý]@x“DžÎ•_µ´BÏ¢‰“Ò½2ÃŽ,ÇåÒã÷¼üÍ Ó\°Í’úTRk ˜½üŸ<ÔAc&¹´¢ËYŠ#9b”0–Gñ}C˜#36)´þ͘Œzž Ìb„i¨9köøëg“ׂდÌ]5êk‰yE°!Gôô)Pf £Rõ¥H”ŒÎš0hf¹ˆU¬h?¿¸o×[×]iâyæ½¥5ck*6JƒPƵRô#9뢵, ðM#š3g46p"É#9f5Ó0Á Åc‘U{NXØÓEÆB†äl6jVÖ@C#9ì„ëQVÆ#´ŽwÏäí›êÎ#´ôF›í+|ëo2|ùwæ¼LG¦=ÜÔzÉFŸmP“\aa£Wsj.H Þ½.¦•Q‰ï#ÆîT<:ÑU«:ç}e¸µÖÙì$%Nû§G9ˆ±µ‹ú‰¿ÔMÂ(MÓ¾˜Om-Z°ÛtBð]Á#3äÚƒa¦$*£’Lˆho’HÔÆ9kŠxÚ\U7Ñ—%e(äµW‚ ;[dv˜dÉuåã,!Å*¨&‘#3Y8 &Ì6F ÐMrÔàÈYµ‚e0Æ% mZ6#32#9!»&ˆØ,5›022lØ9tÄÆ#Å£“z·fpq¶—-Þ)Ž¸]ðõèd­'´5*)PvÃ-“"À´‰šJ¥-#3ÐÑš #3² ©…•½]»#9à’ d3+ÄB6Ÿ«ò“Æ]°çÆ1ÎyWR¤Îx¾¡ñ´nèrxÓïœVúc¨…#9ózŒµ E/z#lðoOP@.Su9r„iašœÀ:2È2N ©-4+.b‹$¾ºn1>Âk4æ8#3ÄrÏ—“O‡›f:T#3™ÊË”r"¸¢i`—#zO÷–ÌÁ|PCŒCS‘€ºçng7§l~˜uÉå}¹N§‰ã»^Ã=,øó —@`dM¨ ">a9£ç´Ùmh‡S´² (…À&¼1'<€4˜Ï—²”™Q…ÁÑfXDª15BäÆŽ™$ŽbªhC@‚¤“B¥AÇeÐ̸Öú­Œˆ¬)‚ˆ J&xsM†Îœ(#3BP£XF› 1"!bo "a0¡¿^†ã„û%æÀ­r.9«H{<2M›cÎãTÂ5õ.‡k²tÐo&å+·˜Phù»³È#ʸYZª¾Æ*_[³ú¿šìÐêk–M¦né#9züÎ%Šœ¬0Ò£§,`0vn$–Ó aÕÊplY‚Å&ƒßY‚‘¿é.r†€9#ë¡ÑÖmÝÀ]æÑD‘¨ÏËG©‰~îÄ­ù`;í8Q.XÞ€xŸðY#3#*È—[·hÎd<´&>8E²^¦´þ4´]"áuápߊ/A¡P|ÁsnÅçHÚe7¿O ]Q¤ŸÎÆè&X÷Óðú ½•,.üq Æ›ÄÛaŽLƒÂ•!5Ù-ú¯×µ¯’÷¨¤ÞWác$ÑŠ˜ÒFÐRHÙY–RÈTb6c-2̉’Éon͵¿>®³#3ÛÑo*Å€™°¢#*¼&iOÐÓYö<ÉÊ©¼Üã =z 0…i «;D$}L†ƒ#3 ïÓÂÙÓ'ì·Gû%ìw‚Öö|Ä€Æèøï¤}M\M#*'†ã×ØŸ<—GðJ7ñŸM½OHÆ¢o‚=R=K8>pÚ̬¿gu›—Pà™õhazšÝ‚‹%ÑÈöD†Ïj½½œ®ÞêAû»Y„#9´‚" DŠ#"H\(1zø¥þÚëü”ÕN“2Ú¾é*Θ+®Òϳò"¬$µ{ßnäI*"g¼îSqOœšb—xqî F•ÉðçûD¯X›4b-i{ µtI-´Û…i£õ¡qôâÍÙBiÒ‰]õ+{ëŽ1ï5kµØ.R¤]i³¶« ëe¶ó®PÓŠ#9Ú+G0Âè'¾É‡5§7ƒe±$×Ô±£Uñk|˜kPK¢…à溓k°´ísIDðÎV©C)¨:( ˆQŽ¥¹¦Ä÷š5Ý. lƒ6»™ä¬ ®„Ð"¥=Kî{žv§-á$Hµ¨1䙚û&‘B#*û“uèÿ×e‘÷~…ôfj<[T²wC„)14O1‰ØW;ºÍ…‡ãõ˜æð'=uéqüj‡™9Ea…¿$ï‰Ëx^vpf3.4E7{Dò;P<Ž¬òQ>ï|ÖÂìê­E·ñG!äÈ#*2T#*Œ­Ø ­åšL ë^®ó€uöXúýÝãKãéúë•ïûv“©!RB/½6”¹I½! ŽGP;+æÐ<‚41uA[œ¿gU~aÏ+Ox©b6% Üt‡<·ÏFš¸ÓÍ6V¿_ ´Ÿsá^¿d£ Žá†#¶ PSïÚ¡liWhä>ˆs;»Ç¸ÁÊûÏ#3Îͳ›6 Êú÷–<@Ì^(’*¦ŽüŒ¡,çÏT̉³LÔ›Èî ùdyLÌÈQã\DÛç§4WC¯î‰D`j‚ÈJè­À‹ù ËjŒo´<#3–#*6lódô*‚UaÁÎr@¢ÙýmJn¢m‘'“âÑ5çÜ#38ÖHÇÕf[É­$$ÕJP‚Áåp£'aÛjN![Ñ2$½±3%Ì'ú:N¥¥'§n&s¨ó#3Rd­¶iã¼ÈÍ3©t,3Ì|=5UjJKa!‹Œ†µ"Ëã¥úu³fÍfasµ“Zч1Žï%»¦Š»d°!ëR·R…µ3¾'‰ª‘â_HµŽ”âÃ12óÜûw^¶ÆM ¼Ã¦Ö5ݤÂc\ìÆ^Jrf<ï;f·Höõ^k*ÆÓÔ §‘YJP4$ƒÒ OUßFÒbvâë(Ⱥkiâ‚שÄ[‹{P#ôºNô÷/hÚr²]æu‚’a—ƒ}Ãm¸M{5´¶Ä“ŽV#®£Üz7ß~U9­‰æ ™ë»_Aö:ŽÝ#*€2 êM‘'G˜ L`ºxØLØYÓºØHÄì³ÖM”ð‹Ž9¶e'Kp<-á¬û¢A[}æu1£vå#9Øà4vL]eÎS‰4`iö w| AžÙ:Ò8+º4È(¸ãw)­SXá0:aú(Æ°i¬Ì´œÃ9¢dïŽNšj™REITiðEû¼c _V{ÎÙOhåM¸íÂYëÓƒ éÅ=5Çc®#‰0rûïOKlË=§ÇE™q¦šž‹;»5^D Xµ“}¯4eEKýÎ؉ÚF„Òƒ@¢ÍTñ߈/Â(oî^š†#3x>©^Ððw%¸xo6ˆœa 7Q쟞fÙÅëmA®nÉS$1'sÁcQ™Ï6lÉßzȱE-b÷ÕfrkYÅ8×”ãS:wº;BÈÚŒädèΤáUnÞ‚Û%”#|O”mªGJßT.›ô6«å·‡³.-B~÷’tžð%&,wÄm#ÒÔj«;ãŒPFvcK.8$“F§1–ïÆÛ˜àêÛåO#9˜\ÌÚ›«hIBgdw¾rø߆Ý=]½^á*¸É’µ&Æ1¡°w²‹ÕÆ#9/ÅLm5ÑjèÑLâié¾ØgV4BG[Ö:ÂewZÚMQŒfÍ“§CSDˆèЋÌ#3Ù±¡bB˜2€kfb‘ºÓÁ˜f.YcDµŒ„I±œ4©u* £ó,X@8jS mb¥â#9eÊ7…4V™»œWnusGíC™*Þ/Q›ËÞpf®"¬›áßuFêöFD$$ÂL„&X|Af·¢WÁÀ=ùNq’¤~úŽ^È‹'CœÌ•é<²éWΨÐë~ë™IÆ:–Óaƒ”Í5fØÚfšzÀ)ŠJŒï)®“\xÐ3 Š.ý­;[4U‰µ:ž[’ôiàËa·æfD"ºa×:ÁÊ0¹:oNKC’šôSd[]”ä6s#*LŽ$¸Ë:ÅZ/‰Ñ³‹âU€ÆÎVvãò¦:ÐÞnЄ­1éf™­uÙ­D÷cð£âXKËh‹£…¾7¶‰KŠxHÞ6:Íb `ÒUµ>G0¦<ôM–˜xÞ±´Ûúma`¡-4C #3z1ss´uåÊÓéÛP+ÚÆ”ÕH.1q!Ô1¥¤”ØUT"YF%3ÈõüI¼êLá`Z”ŸšGæa#*â–²'mÜkbäÄÅ8…p92°®è‹#*“’¡é– €°ácj8ï&þº7£Ž#3`>)xݤ&“.™>Ì–aoh§.ì3Q¶ÐÉÍ–#3Â7Óp»•}ÜèÅÄÕ‹yyîY{ƒ†·lÛTvYÇ¢֘ƹNqm>;˜Á…·Y¦úðn¶j¶æή´ó !Å…Ïï;œEÚœ;|>øoY[¬Ñ&&ªfPÈd¦x§6—1o …€Mräê`;9„a<¹„ÃãŠk(µpžG†SbŠ¥&ƒ|ì7]‘ÐÍ·»Ík4Qá[ÖCÊ%àã¢Þ uÓªn^|~9æó¾ÈGIŽÄÑnOU3/¦Þ$ò‚v§À)6XH<öˆò‚âR2·*#3箟tK¶2ÅFeá$“À¢¦£ƒ,m•«"Æ4H±> åf¬’…šcn·æeó2ša4™8dƒGÇN7xÅ¡ã#‘éÁiàå$Ê#3ªÁÖFÇœL×%ÖÓÓ+¶Í8Y˜òÇ‘Õ]ne1Šd¸ì”N›.kÏfλÞÙfHìå¥Í¿Jš¢Õ:±6¼öÙWe$>íuÃ8YËUøê¯&ÃdŒ×GŒø¾Ô»=„ìíM„Q\@媫–0Ä ìÏc–œV±Ra¦é¨’Ÿ(Æöò4½v=àÔ7Á"aNÛ(ŸJ0àfD›¥é {yÍ©zX*mBpä"Œ8i¨($ÔÍNV3L##*èq…FõèXrm\1Ü&ÖÌÔ¯µEKÓ¦tWC*¦(¹T„Žó–ªXk¦™‰aðìp˜‹6éa¯ébó]¡Õ¶ç*ÖÛã<ð&A·ÓÆKi­¼ìÚM†©ÙxÁ"áë€`T’m)L;ÛÚŽ¸Ø›fG ÚhèP‹hMÖRA ¤ëӃ";f¹¹m¨K‰¬0Ýv=IÛƒùT .ÌìA¤E¤ j0ÈÒ#9*R¦•@ç|3+„Ræòœ—Ä!…ñÁAsɲ˜v}ôDš¤‘Ë ½`Î2I ÖO¸p¡ß<¡ò6Y#•¶­,Zd«èÿuHŽq#3¤9 ëO|[å‰b£h­s¤¨H¬lLbš•á0Îi0bg5Á† wåt‚“V¨Ž=d9â$õÐÑ^œí3O@å‚ÓìÉ»85dцÆkfa0ÍA¦&ÔÙ)›Õ((º3&õ¢gJ*jV–S-÷›I–†…09ëZb¦É)!…t­“‚KH¶›#3°ßJÝ=Y(00u©9³W‹8¦#3Yl\³D#9Lƒ”ɇáÎSi *s@õ§pòÚ7#9òæ¶ÝÒópÃ)Rð f‰éE(Ç+¯·z;)ä­6Í´t`ÁNŽLà“¢c(3Œáê3Ñ™r™´C‚(*"!¡ˆ±½æŒ#šÒƒ¯Ž5Ü]¹N‹§0Ü6L>ð8èOѺï#¬ñ:nu¾P¸F†ãj¼ãfcNn'òú[!ÍŽ Ë@:ÃбŠ!™Ũ mà…»ìhÚ°2¬Fvµ‚bÖÄj`Ó—ÆU“#3—Þߊ~ª@4LbîÅﮬ]"ÐÖÎðâ„.ŒkzÝ-8;ÖÏ©ÏQA¦tÈz殉#9˜Ãí/ŒV@‘ÅÑ• àãcðwµw¶c×y[Óe–¹ÔP £MºSî™îÊGiŒ3Pš4Ðp"ë ±þ¨õÇa®Na!•]HSo*5B’E#324I4ŠÒ Ì(£­1°H#33 Å`èæ¤$­­ˆ-‚,iÅXlkF¥“ Í¢gw'…\$Ì]†‡¤ÁÚ#È$Ë#ÛjHÀcfÒíÞñùõÌ-—*ÇXŬŽÿ¶©;@‹ÊD4˜ú #9PBë¦Û`qÔ”W:ÞtÒäXšˆgű26ÖD”º“!.ÙØÃ4†Êˆl6Y¬Àr›iS¡L°’Íõ¥—ƒa6™‘’4daÎî3!¡°Ñvf³ b°œ#3V9²b”ˆ‡Pç(°7b$c…Éd‰¨¸ÎfÁ’€Ï2˜°ÜÆ Ž˜ÈNèLn:qÆ- #ÀÉ•°E6!`háÌßF8m㸰\L4†cwHsC9£8Éq›I¼x6a4·Ttf!¡bp%s3T2KߪòŤŽРp81ÊMT2,Çi˜4Ü.f:›—2èj:.†Ü„ÉÈظ20ÔC9,i‡a¬#*¼¬KRX`Äõìm6RC,1©[sFY͆¡‚q$ÈH·s[†–0ÔäܹšWY¸›*R¶LÑ“5fþöU‹T–¨Pý»#9ÂH¤ ¢m€f±@Ø€q`éˆ#3*oÿ0D3,nˆD~)B##*A¯ðÝý¼Ô&óêr’( ÅÛÓyøµ‹ë¼«„XÚÆ%©”":£‘ùüæA˜ÁgXª0ÄÖõÚS Ô°Wªâ$„ #3ñZÑ[”h«x“[´·m•¬ ‹ª@GȲÖ4€@Õ¸IH;ÁiîËlü‹óºMƒ±ZO>âÌ?wá}ÞÕÙ‡<ÈbjvD*ï1Œ?êšS¶HÚwð—ŒYó™zmpÿR6Ô̫ܳ«‹kµÁ«”¦kFñ“vuÖQEÉv…ç\¾û\8¡V]"9y‰šâƒÐJáeñPTÅ”qkž/d5nªeTàá®Ò£´Ú Ü–‚‚7„nÂ20ƒ«u8%¶ eŽxn„`èêÆû{@Û³#*E†çƒP#9d;Nh¸:‚Ø,©1@à‡$#òèþâˆ!VíÓJJ×e[ð"d# ƒÜ9œ –CB•C#z PÙ£Ê Ce@æ L,`˜ÎÂc³£‚‘3al4y.¥HQU­ V ´ª1ø×¥$#3¨6ªUŸwÝéW¥ ™¡ÞV€Î³w–`õáW좿å½H0ô¡ú`¡AU@SÖë»2æë¦íƒF¹²Wóך%ÒÕ0GC#3¢~&ÓÓÅÆ"ôC´zˆÁa°Þv÷1äJ`p^‘’‡J/ð`©çÔ~éÁø™ÓÜPÁ­E¸ÂŽ§ÀÀ| #9~à?Døú{t37/½„%ŽåÖL‹¿¨þÓÜh¢Èaés~Ö¼=ÿäWÔÇn”‡s¡&¸šŸ{ÎF^dÒã£OFÖT*†±„Í-y.UÚïwžc[qW¬·ê¤-ŒtðGJ&QÏúš0s6“Bši(±mé…D¦GˆÀ͘ÂQv´¤Î‘s.„2‚d¢ðï|Œ‡8³­¤D¨j4xŸ‹CJf‰ü¤CPò=—ìŸÄ$’ R¥ƒè‹M)(,Uµ|ûô_Ÿ¯æ*ü-V›Be$¥±µÅ£i#3mh“‹" ¦™–ŠÁ¢Û"å¢ ""–ˆœ=ªïÊ'É.{Ì)“ç#3#±½ò€ŠˆB)nå:7÷y.Bd/"áx°’jxAi³ÁS½ ØTh¥2Ê?,]ˆŒÖ¸³FDCT d¥5Jª  #*Ý©4Ð9Ú©Kb‘"riK9ă2€o™`á=ÓÙÆvÏeÏNî™Ä8*¥¾Çœð¢×Øð“ýK°Ù@¦HÿoTŸšžÔ°†k†;ZÚ’û­CŸð˜7DÄÄ(h‡ÙWYœô¦& "2„x¯¡’/„ªÖ]Üüæó¹.:Y¾Ýkƾ¶£QmEŠ¢¶MZÅQ©¥Z“jÕïjZj,‹óG×mrÕðAü7ñHäúzíÉ8ú¦²è†òFoí›s¤Û×r/èR÷¡ïr>ŽsN¹«ã/‹#9]iéoY_èŒKqhWFãí±IQÒøž—/ $®æˆ–ÑÅkÄƳ½ÚËUNCQ•…s0é´¥”[Ó'̧‘õ—ŒÛi6PÚAZ…*A¨%¥.´£Uuª*„f§†ašÞŒ Ú.2³¤3¢›pÔ ÄœdB9>–Xô<ÌÉœd™r9†ôk«ªÙGÂÑf-ê ­òôŒf3®•mÉ¥ñM9ÂLñN“tDÜÉt8Å8§kâT8& v\4×Ktá¬mõ528SŠ¯i¥SƒãkÁ„&'Áðm)î7\ˆtðçKx«MÇGƒ(¼3ª×.^' ×.ÌÆøÛ™"Ó»#f¦*¶}îHy”Na©„Éf·]%ЭðÉ´Ìã¶Ñ¨Zz[ÌNMêyC;œï†™d“N5•ÒËjí|AƒŽ†©3>aÅ"Bt§WO±¦²XØE#3mCš`ƒ—q§Á¥¸üf¸r Ó`Í‚$"0‘aÄ ó€clÙJPE„P¤„b,#*ƒQi¨ä~t#*Xⲑ÷í¿ÕT¸ÚXȪRR°Œ)pÂ0u@hX2ÐÁˆ±±6ˆ(1$”4 I$YÛ@äX.è·#9T¥GwH”¦ÀŒ„"”º7B%a).õÕG8,hX9ª"‹b¡cY*#QIZÙ¯s’»»h­v…ͺ‹²Ý6fÅÝÇ:V¤e’¦¤n(BYGmÅ/XšÝ,Ór®…]mÕ\9Lj°ŒFD£bCª¦›[u+pØ®ÍFÑ ÀeN pïÉ´††ªÒD BÅb½¶â¶¯)[2Ô’R‰³m¢Ú6Óe£S6êmºme¦Mie¦ÍV–Yö¾Ü¯¯X¥d¶ Áb´Ê6¬•TZ´%ET#3-“\·»Òfï#*4Q쎗6[ ‹»;(u@QèKºÐ ùÊ‚?8€—‰ÄäÙ‰0h‰B 'l#ùù OaTBš¥`Tˆ¥GÕº(caæ|,Ý1:FC±#3?c KCßÑ€BÊf›>&ß³4óóŠíPúX1³mó_F~8Š?-/ΫÆô£QÏs#3`ÕÆ ;´zµå¥¬­bÜ ¤ I#3žÎÑ&d©©c6«M´'ÓO#¿tnÁê Ô›LP!ûŸÏe@ì`½ ÕR-I#**e"6AH 6„S  #9ŒÉ”0`PëÔïÝoh–Ñ{ø_-L6“!e™Þؼí}Xlˆ,çSð@á¾–©p-‘"n˜om.%…#*îÍ@° *ÚÔ©”Ì| w"@ ?,€j$­°×ŽÏoò¼wôê^ ;Èô½àŽê|#9Ø  #3“2¡Æ†éÇ—÷pÖt?‹:•û OEo\0¼¬Ñz)Ð@¦ÑKŽ7G‰Õ+ý^&Šx³Lnš#9Ѧ”:`+“a®IW„½!T}n¬$ÁÎðgÁŸb„¹¡ø0é‡ ŠÈùlŽN_#6[À $ƒ,U«s.Ã(Dð760gM‹™Åâ/ÆÔ@VöD¸Ѿ¾?8ƒ÷6ûæªUY­¥T¥¶ÈŸË|¾¿l!]G¾äÙð$¬­cîë,çdñË•Ô$_®#9»hQŸ·øL‹‡ábŸ²å’IY~û^õ[½NÉZ*Èwö>y¨ÛI‹©DÚKÛµÕDL’o¥mR„´Ô–éWdÆ©yJ­É¦ÒØ¥-¤ÙFƤS)fš’Êd¥iŠY­)K}k¬)dÖÓÔÝ›ûnåM¥(©‰6Š6ÚÍZš'Ž(¬jWuÓjû{NÛ5{õØÑSAS*¬£-JkRU@jhÆ“*¿˜Õ]mó¹Ư~í’kÚ]U^6áZÕH’am5µ«•ÛM£I›fÉ©[2õçW…*&Ói²Ša©« T[-–“zvÚÔRÖ1‹Dó¶è¬ÙgŠòòw$¥Zí;&…̳]YªJð]e¯Ö,¦%Ó[\HÛxMv1j[m,9p1Çœú1k´r=7¹’ÖX½<9Ë ˜­,#œAéÈù|»¨õq:öp­U*¶…^ÐŒõ\^EÍI4NNÝ>®0\Dlá2/·Ž«ÙñŸ>s(Ú©‘Å´aUŒ¨â⥖èňˆ„RL¦œkQ€#*,@°”øwLÔ´ÚXM5£m¹¤F#*!B{t„,Þ±Hv2N²Y¥lÒ¶öUk¦­Š¯¡ÙY¥ævŠZÜÛãÝkÊh(‚¬‚TYk…*%”Š™P éM”vni2R*; ¼«{6­¹dªËfÆÌRÓ3ÕùUÑBQ©I­”ÚÛM³LÚÉ­†”Ñ¥Jmò­ÙC I–¢²±щFQ¦›$(ÐÚm”¦‘-%M#33̦(,F2¶QM“$–F…IZ4X±b©J ¨©M•)L™5’ÔÊJ¤2Y#jQ#3¨Úͦd(II‹&Ra4É4ÉRʳlcTIVD¨¥‰›Rd‘f­ieX£%£JRk)ª–mµ&Ûjõkkº¶Ò³V›I²´†’ß mk¦Í•ZX¦Ú²mm£UîÕæËÙjæÚõšÖ*Ö5¥(´šV®UiZÒ¥Uohµ#*N³¬þ*; Ó5µÝÞOHsvõß~O3²áxqÚJC"À±®AØl+NZÎ=64›6cËb‚þæ0{$íïÚ?ÑŠèÎQ5.ùCŸ"Õa#*âDÀĽ;ùÝÅÊyì©Rhy»OG˜R<ár7‰ÏuKTI}¸qè¿ñN„U™ïDåÕ{§¢#¶=pÅž·ph]†+ôxwc]:é»Í›k(&cÎ][M —&JQ»IC»EJWi‰u^ôµí^ÞÜ+?ÕÈjÃߥöc‹Ù×(t)ü#3…`E„—„X!!¼! p)ÌækHƘÁœœa0JSuêï>º¯¹Rû›Wç¤wïÝô#*T·M p~?í ƒé6냅Sjnˆôô… '`ª#3~Ý<®à©å} › g ˆ†Ÿ&„u4×áFLÌýù'âü#9$S1<‘(¡ÁÇÛ};5ÇŒo#½u.“J¡¸Ø˜¥Ó/0à¹`Ã;A&…#3Ô³D>”dŽ¾Eë7¹ø6*Þà7P -ߨ¿Ñ3·Û¿ÎÈ„¥§°T™Â ¨¿ÅPúU.FÆ©Ñ)iû&÷+!_c‰¿=NC|À‹$ŒìªM*ï‡f>wliIí© àtg)’s1{úVÕ#¶Q¸FO˜aÏb³x‘êfËàßXP†eüÂ`¹á#3J/jPtR6W0ïŲµû¼¾—¿­··iÀF¢Ò#*„.à#*¶M¶5T`Û|Ò®ë¶ä=NέôZ¬#ȳ²-=l  AdA¬‰Ý×K¢ò5µŠíª²J+›žùãzµ·ð=hi " dé^!Â&yL2Æc‰V©N‡áæ ¥š%‘>ˆâµLÆÊsŒ­YT…bˆ‰76Ù¬ÀŸx’^BBa'‹:ÙÚ#*C×°9M}/‡rì8öz£yÓæØî¯o;4´¢°u#3®¤9x #* jëï¿3ãx¹Ï4 ®ôH~ÖþÏöE°*å ³®@Ì,PPÇÏYf-­a¸€ÿòÅ,`0iÍTPÈ›)2~¿ðÚîËMWZ´»©H¬ÒÊ  á¡kKMkMÔ™FÚhX=á3S¢¨»â¢×#3#3‰6C’=Ø,kCh§6ª Í´s¨bkXác›*’ˆÂ÷e·)Õ¦P‚·lªE͉†D6'“hn³¢ÉœÕˆæ…ŠŒ·T1†”*ªÈ£]—I –­$ŠeÑ•Lâ¡HkŠHt_×ð–l BaTv#*,íéç“]Ræ²B Hý#9©®Å¹œ¢N„5´,›fˆÞ€ä£æ‡ÕA¡ˆbVÂeMTLX«BUÂÆg…r>p|'DZD×Â=pë*W»ž†'Aí‡cs˜aÞBHV2#Ôhfo£”ö=®ûŽãêw…KŸKYKh-â"Ô¸JpŠ›÷mïÙ}Cú÷+h½úµ×,D‡ÒÛõ¡p"Èê;g ã®û·ì'§’ûÃÈ/,þYÄ! i1ú¦ÕÈÔ·h`”Æ/îW‡äw}U¹%O 'kYŠ¨ikÕèqɹ$hXKÍ8B÷¨JŒM#3–ºQ¸ƒåµM)#9M ð2Û,›¢å·Y0n‡¥³¾ ©P!+]¾7‘ý[˜eõìs¶ãõúë=+Od•¾ÍA“T¹ `$"È Æ cá’gòyq$Pì#*èP7'#y@"l»R!94 ,Ý™cg#9*]¨ìÍ®a¨Õ –ÕÄ,¯ç7Á#¡qækrY¥Ï<ëAâxyÙïë³X£i ID’A²g#3ká…±:¢צFùÔš# ÙFÎI»Z#xÙe°^Ç# ðè!*æô®§†Ío‰-F4ÌŠîÔ[㎛8/¨ÃzÏ(éå¯Ûoæúàg·êËB}帆(t»µÆ²6ãExß`drpŠ’]…ŽÑ,'Ç­? ©×Å5T „å¿ÃÕŸX•P$o|ƒÛyÏבé´¯°Sp(œZkvRåØnBœMØÎ<ôˆ@ŒHF@ êì2Øè-~Ž…–’k *š¦#9²0û?<Jî¨U ñêúÔôlY¥ð¹a/#*µ)#9Å0geT’(¤ Þu«ÝËË—xÝK6û®L‰™bHzóoZ×­]d“#7ZÖi]Uð»ZôŬZÛÏSÁÕÍíçYxêwn) mË‘¥ì€Êš£hjÊD«)H’ #3&¤mת¶™y®Ncê#*¯ÀÂœ|vê·C~T°úþíý# ô¨€E»|„55¸¾ÿ9Ó±ž*—kŒžOµŠw5ÝDbNv|:æe_ÒJô¼kð¸²C(äÐ*Ã…&ÖCLSµ«ìJ5dÚ«#0ÿ²á `Ö©’Æl6[oŠ×º¦š-ˆJ#3µk›TÙ§gi±»©t\ÕÐæbK#Qj-F«ó5\ÆbJ±½MWÉJ*¯fö^Ók^76ÒÍ¿‡øNñª’µeS#*‘ B1Á¸4Øïb£OƒË5’¸Q&Œî|ô¡Ò…™O–4¹ »—‘p*–ŠÈ­¢ÔiD#*€D´MÄn`ÈÈ/¤¨HD€ü d‘Íç{…Ì+AÒdh¢`ƒîxÜ/9Ô$¦¥ÃA*I›Ca Ï0Å‹Cû±öäÏdevÑl#*‚ 'ÂK`ñ7š·®Iñ’ŠŽÅó„rÕ”¡9Cd!Y"6…Am†ªÊ©Teª³Ê‚¡WK$š¼ä3#9eÉ‹"‡ªº¸;ý4d;Hÿ#3T@¦æ×6šmÝÖfc,šÒ*H¡(#*#9AMC»|¯!ÐÀÂ5Åa`ÆÙt4ÅÐŽ ˜ê¤ë]rJôK½GœDBœÒ„ýù‰ÄÜcÕœùt¾ðäò'N Z ³¯PVA—Cù¤¥°"#9¿1Vt1‰âÃù9ö’íPßD=~?ôaÀ+¡QÓu !´.¶†œþ3v?³%Æ`€T@Rñ‰¨7ïÅÇ5h8÷X>6ó–¬ÝÔJÝj¨Fá¨t’@7 ¿¥GAùnü¦ÚLÍd7¢_3~×+Vvö'۬υ}¿ßz#§Ö?;^A($k(•#ª €f!»¬›~Æ„õ_‘áÚ3À{©ù#9Á­g7çõþ¸zÊ#9i=™nÝúár-#9¼ÛÏ‹9Aר„ÙÓ¨@a$ALï@Ïc2Ãðçüp@ 'd¢?0PNÃp:q…5E6 ùs™ÞôúHEþƒ½p!Û賕!è"¢’H Š‡qRU)QDJ" °P ‰h ˆ@£Ax bÌPLJ‚#"Y«*Rz´6B¯¸¨ÜÐf1‹Ãû ƒÚÒÒ ’º4+šK]#9ò3È_–´u9™Ç4æ}Ö>ç°ÕùPÜ=;Uƒ¾O°y¤›“Ԟ䣨9{%Þ)·a2—_*~{÷/òT1€ÆhŸ „È&h›·hʤäPöÏìÀøž&Q@[xø×€í¸°×rdPÃhfØÅ| ´¨%6€ÃNYxe¸µìó±düêDð"väB1X¾ùH.éÖïK´µòmWàªt¿0çÛÍ~äE¡"Ž´†õ"þv´ÑúY†(Ç¡£ ÕH,TU#9 ‹5ü–¼Ž-4:ÄfÉ(Â6€b±Ý„Æ,e–…ÐÉ@Ì2#9<Ãû™xþŠK#3Œc#*ý€ãPu‚cIgLÕøku%Øop ÇUxåÙÛ"“(««k–8cg$ÂÕÑ!«’LÂ#92dYÒLÖ[\K‚0#HìË`a$w È&`QMJ¬Dl¡F"Ú¬ÞThÈi¡±ŒÊÉZ0cR5 ©‡ƺ°Šê ¶#*F’Bø.j½Ú\´mˆÆ´R3›ÕÂlÒEÎh0†#"ì–f¡3½IzjÞísV-¸c^ÍãdÚ¼hÒÛB+²23¦«–=´!`Ä3„¶ £•4fÃ--`¶RËdÁÍ.»;¹‘½¼0€Û"¬U£taZ5‘:›»X‰½U œ]dÃGl†nx"1^NîÛ–ÅÍ´m+º4j+Erܾ#3âyÜ“=uã^7Žx¸Ðòë¶ù[5É-æC–.ÊÔÙÖApÌjÓ´KƉDi:3©îÖa¦XHÓ|8—#3jÄÆŽùáåB¸Ô›:¢ÀѪ Ã.šH¶2¡ @pµ­©ûrÍ3ÃÐâєȼu7¨#9¥ ,dtšÑœVºq°þÐÓÀö(h£=E0NÚ óüæúHm-·Iê©0!sDÚžŽN¤.Ì=*–?q»ȚªJÌoµ]ç]yF#3 HÐƆpŸOëÇõR”Â1Ò² Ñþ«Û‰Ë—Áçô·½ú:#*ôt( u¦Ðª î#3ïñÂ~0h…˜IS¸Ü…«Fe£U¥¥VV›ãþ½#9ÛNèÔn^­¼W-y.m53I5&šå¼šM»TcJ‰2\·IªŒ,V(¹[I¶º›c[j§Wr[d±#‘ÂQŠ0µ„Gdn¢$´ó­F¦i-¨Ûl©­ûךÞý¢ùƒ0)Ì°ïÔ€"¶#*„ƒ*Ò?ëâxŸƒÝÏÛ.§ïˆ ‹Ó,̼?'ŸÃÏ+OpêQc/»Ôh¹!£êتøP• QBQ “ù¢¡Z`ƒ÷(@UHÄØÀò…Tœ”î¼úœ´¸6ï¾úøVOŒ¤{ÓW>áÉÌ$#*IØ…¤GUL‚úCíºÐ©Ke’’RnžiT›[–ºkκ™RÊ‚Û»¶5¼Vûmµå—§DQl–¬J–QÓX¨®«º¢¢ñL¯D„/CLR¢55Š—€Wo[ºŠ,Ĥ’¶Š×DFˆD€BÊ›ASQ; ¹ÅG¨1Ezá#Ζ¥cùú½bMÿQ¶°I”WÀ¢‡0ðb"0”+õ,ITRäG×4#*‚—† e†`ØÉ–@2…‰9$±’ñÔF2UW¥Ÿî‘Â#9lO„FDX$†51òJu#9R¸…Þ3#3¥¡Âe±—£zÒؤ‰a=ëð’#*ê¢\qì³Ê«ôýõëô×8¯vñ{6éî>î¦,@¯Ôª©› @²,˜}64ž»9º±y<ñ$ƒ!ïy÷bt<>”LõáY\u*lŽ×“½èÐá–NW —,#3ÙmÆv®ôûbøEJ@†ÿ€ipz8¥&Wä‰ú¼u™%`È{ÐR¨lã·‚.àÃ@‘¢† (“mâJ¡°b9#*?†ró#*8|§¬ò=)$ …#9ª°EÄ&á<éb‚7ùähè{Qè-o_zdeïü·ÙÒ…õÖj9DÆ#3z¶ð\«îX²·…JrˆÆn˜aj-4I `fOíû¹ËËÍY¾ÇQŸ©Yž#*Σ¤«“g4Ä~«#9(jcx,‰çÊâT¨ìµ¥QQ¨­Äl°X˜”Ñ gNäžµÜÛ0ÄLOê+¡F‘4”L ¤# J6ÄHJK•3»b£*¥ !?‹¼õ_—s+é¨îÄQ–Àn"0ÀÝX:¹ö(;l™ÜÛýä@,ýع¬C;/ðfJIa°:³^QŒ/ÆU[±ÛÃ]Ï £[5¥üÓx¶uîìOH¨zŸre ÇS% ?²M „rýr≀Ïò©a`h]B×" j|±oWÂ"‡'p4Œõy2Aè@ê Ç°h…¼çjµ­i¸s¤Á±>ã?A—§µCG‰‰#*  ‘€匠îÁ7/•,£ËΊc¡pq”…K‰õì5OåstWJEkÔEi$4ØÑ$p¬I³ö;ê9Ê¢Š,ÜX›K”Oò.}Ç6éyÜÑFÏžëýÆ2DE4Ú½ØÛêáfš@‡ZÕTæ)öIõt)¡yCäeµ §¹'s­þ>0×#*Nœ+‚k Pyq´qÇãßç–Ũ²V4ªMŠE$ZÚYlk aB÷ýÚðãž7oàû›O6¡#*žðsY{ò;wäèû&â©Yć6ùßaì )U®ôéã˼µå&››·.—4Ñ@Áñù¼M=F{7­ƒçNt²E†XÄ!V #'ŠQˆ¸(²¾c8§éðÂñNûY¤&Ió²bi]Á”€ø;¼º¼¶²’¥,Í÷úê-|:ànW\„i¦;A…$m¦&ý¾ïäIJB#3™žÜX11¾ F‡§°¶!d\UU)— &Ù#*`„ (^²©€hBÜQŒ`šÕ§¶âÞu=Rñ 5³&?B«BeÐ& ¿Òª(ÚA#3¢È$ éDÂ1JO´ë¥vGS­cG24H‘1C슺`£H€>>h/:ÐE#²wñQ Fií÷zU©ÛXÏqÖo!Å—žiY5C–…äôÕ5[kœæñB!9a±òÎ ÓƒÀ·´ª(ºq… ½3úô…··üÿc)S»Ÿ¯mÈ·ÑlêPPÓh#3$—8††I˜I„BîÀA`†#3!Ih¶XpK” dˆ©'aŒa[ÙâPyëL‚žâ#*Yç@:Š&þ^ÉÙö*¨s&þ>‚݆[p­A —·훡©3#3ÕäuÚ7ìb!™§Y··ÚL#*HEDPÞ4]a ›0“ÓžJØ(®¬l6˜»þÝ6©LšÙM©J©MkßAÐ÷Á6A¥ÈGhý0{þ4îîïfñvoäxé™6p¸îóîÒ&â"û_o©×lÏ$ëô#*F „|ãL#3¬D‘–…€¢½)èÃŒ‰«&n»^+¼éºó¼Š×œínÑ6Ò¶ZÆ’ÛlkFÖKY66³1“LÑÉ5ÝÛW.êÚòÛÌéPµ(Ñ!`£åóê:ÅÌþh‰»}lXN‰' krJæ4SM$$ôøU_÷¼&!j2ž¡’[™‹– SäV1×"0ŒlÆ$FmîÁ¡çX°öÛÚÜ—{oiiæ‹…¦\1cXd’øÔ#9A¸– l#9d²Ø¸f‚’F«J2 Ǧ›º¥ww³hñ¦ëǙ͎•3ÞÒ)((D´—½“lI)à ¦Í¹”VuLXšÅÈ”9åÆ6žE-Ý0èñ#3ä3l­DˆH´Ýµ³R^…#9pÖ6…þ]«@šT¨­G£·¤¬ƒžwnTÝͲ9PêPnb¶[1#* 7(Ïx'´ ¡ÇØo”/iÉLíä¡&Ä•¶Éb;Š¦D\t–1äSÓİÛ*oôJˆåèóÒÒç([¹ÞŸ@€¹×j]‘ûëtÎh¾#*µ#9ЯíÒ¸ÕeV‰›)‰Vêw’uv²„¥:à jýFÛ}ö·™X¥3B£ZKlL¶6-&ÕF©¦ÚýEõ«²euÖ©ù|ó—E^+\j%D ûgqá)œü¼?[ˆ<îXJ.nêmS¤9oõM⢠=]Ö³VB¡ð›C"…<ú{ytò;~Yt¨Ö.‡ÕÄWÒÿ1ó&~t^Ø4Âe¢,dO­½¦ÊªLbzgüöÛUa˜œa¡¿¡uiv›f˜œÇtö°Ôžk[êf·L$›ÙA¿KÊe“Æ{.çÒLóáê8<6fö!†€Î& sZRôzm°ŠjHæ@è:ö<±I‹ÛBäÏVgy’# Æq×\yuèk®€h7·‘¶ùgI©Š@Xj3(]ƒ” M̘4%a¶\¤©¿lT³0[E2Ñ ÞüŠ_w·Õ¶-Ï‘´‚Bý¿ìžYîqÆ·âGz9öñ%ªì2u‹·“3'ó Ë[\¦Ï¤¾8JyOžþXã‘h ò¬øï\ý·s^{ZÒµpí<½_Ð)·j#ë/èèÈ£H`#3»‡•¿DS”Nó0¨~bã*B@•v¬`iÊ5y"Sw׉tØí0foé#3>Obc‰Ã_)90.•l¹C7·öÃrÛŽ%ÿ]ೕJ×BèÙÐ:ýÉOª…f66vëì1„ñJX/U#–GÑÓ/¯—…Éc|ê€ïÔLƒwL/câBŽ£hò A)¸£îÐÑ`2ôAKm¢#3üúé¨Îù˜\»»[Ü4àùS0ÜyÒw€¤D=­`¢v±áP#9ð”Þ.Ô"RQU2å ²Ø8œ›,@YW¡dÒ¨–Š°¢#9DY!/ÞTh"ô!”7ûv^ýE·W#3ˆp ¨ÝîåÔ˜I-Gëü,l¯]6ÉUR›´Ýs¨Ðëh±°!A u¢d”eqR$‚`Ýi´@NÅ#‚’J \€A¦(7ˆ­>àd‘!„™QD–8#C¹¥(å¸Ø}W®“ËŒ"ºÎÉS<úŽìƒÒœÇÄ£¥Û>iÚ@Ùô{n·ž5LŬZÜ¢ÉЇ±WþB #*Œ~x?OÝ]Xè7ΪõWztßTC_¬}m#3:´ÝÑ HnÃV,°„²Ü&…“ßq4Ô#«õPbK€“®©T8i£ è0#N»‹‘ä$µ[~ñi¡.«>ˆ‘XHk™Ò™¨!¨ßÍ jOA±BXðö ñÌ$ zxÄ¡¢»D ÌÐÛÒN윚F"SPÖirâ2;,©V‚#*#3¸„b‘Fˆ Ä–¡J#9K4A²UZkUÕlh®f^.^]ÞKunÛ[ã,ÑbSR­³ZÕ‹l÷ƒ`ÚuSÃÂQ @ú¼½ÉJÓ^¢”cPÍÒenƒ9£.EI†A#†¾šdB¢é jD1BkŽÓžÃÙ ÃÙ¬fú}–‘ádjC‹˜®!`Ëûš<ðN€SŽ{T›ôjE¨(]ªO¥!i's ‡Ûd¶°Ú(DIÄ'?%Œ‘ž8žI²šv8‚h¦C,µÔ ¾'{v¥€HhltØ!c‰#*)ˆ*0ëf‡Ë“÷ä|ò’I;hd³3«;†«7ð×Û(ƒ–ÊÈk’#3©‹„ѳ#7Tip>ëÍÀÐÀK“"OPhx…™\  ´#3KéêxÙÇh ±i6ÚÇïb0ˆÃÄ<`ÎåéÒÛo³¦2‰,2V1HÂýZŽÆX gÄ6²«.’@ËÁöÓjüp‡#3ýûšOŽÌ”(’$u³’¼Î •‚Süµ$¨x&{y(ð8í.Œž à Ii¸´Åÿ6fè^”B9iú«f­·©] #3~×Ý!2ÿp÷êØG%[a˜ëòæóÖ"*§“Àd¶vhÀCbZG¯hÑôC€#90í§©¼’_žæìIA·^SQ‡B’‘¬g•åª¼C¨d<“ RËùø-ÏìÚùñÏ؈¿a„ë‚ ^ª*†OAÓGBfyt)š©²"¦6vn¸ä©Î(2Š%M·#}MEâ×íÍsm±[Fª¢­­ËFµQ£l˜ÚŠM¬m’ÆÛ­½*ÕÍc€•SsåÊiÜjh¾;:¨¨ÉiÕrŠæ#9HE–Öb0##9²©˜\¢¯E‘ÚˆT‘bùvm8M·Ý¿~ÅÄA–pw¾ÂÅ7Nêø"`ŠMQ__¦ÀÅî;ß%oåsŽyBÙ×õÏo¥Â¢˜ø#*zöÙ¯­£Ì4yïFSc$$†ŠÜÓAáA2˜Kî^’ˆ~ŠîOÖ ¤ÚwÆ¿XûPR’#3O5lyíÌ´î÷c;ÿI®šhù|Îã>œšøøŸÑc×™†!¬M".çuݽ[ä ¥6·ÁZìÛ”¾–|gÕ¬Â÷ËGL¸Ö=?Qôl×­é6ù$¯¡­©æªœAʘ¨Èîá …Lª\9FÎLò@e¡‡j+nQðÝ—Säš#3¬‚Ñ1zÙÕ`v®W,@&(*¨äÇ“¾“8è±Dè@Q<æá'‰±ÔÑŠëáåì<½à9Õ ´±¼swF!DöôºÛìÚz“Ë5:®s¶pJÔùfaO½¥n½ihUzÑN•5«³fU²¤ÛjјAIL…2˜Õ#9 6L\ ¹ EÚ‚“fÁ}p52ÞÂ9#9]ÈB@i1¼†TÓa\1„TH‘ôÞfíå5MÑ]™nVλJFԤͱPÑh×]u‘0&}ãÞ<¾¸„õ‚Ò8Í#3&Ä7ªöf¢Ì0cÓI¡ÆB­(ØÓq R#*2¸ÜzvŽI¨’c°n‘Mb`±0‚$B%Zb%‘#ïpÐ61#3¶Î FÖý»‚OU$?-Ì„5,Ô`~™°²‚µ¹B¢2#9@"#3yÝÝÕö§¥æ›×\Ù²ZÒTõÝ&Fyºë"JÞºâ”ËH_±¸.FJ¼ØU ¢Œaˆ‘Ût„CPE#9@­TV#*Ó#3°k,­ VcT,qƒu‹<­Û53(Ð0l&¥¶SSC)±¨Å©$4¦Óbeš¦š&F¶SRîíåÚ¹,îå͹0o^¼òÍêë–ÜÓ·Wi^½vÝž/^®M*Z†‘¼jø{]{=™°Êiš…åèÊMȆ¶¦TÚlJPòÞh^ Ð0ÝgaXD˜Ô`ðÙx7•l@À5²¢ŒD$ÇmqéMºëÆ1¶V ø—N\ãZ¦÷i±Ž48!Œhä`kåUkH±lik":µ”ôqàÒyí¨ã&ÐØС MÈѦ*UEä¶ Ã2Ë0Åñ²¬c7³$¹E±j"Bµê·J(‘¯vr‘ÄŽX£‘GVJiQVÛëw–Ê°)¡)*’ªEEË!h(bEDZÁœIDJă½ÃFC %(,º %Ð1#9Eb)45.âv¥Y•â²#9Òˆiän0-¥ƒ$I˜Ùi%ehCÑV‚Žc*5Iê Œ1†í¹BÓÇ.qÂ#Q†7”x†cy ¤nÁ²á†djqŒÚ¡»±•Ç”­KLMm Às.#3ç²ÖÆã5d–/¡¨ðÑ>Ʊ˜Û6ÍeÂ5FŽ ôÊ#3žäæMÙÃÚ™xÓlÀ—•jÖà¨ÛE#û[Ò·»–:N`(³ÊÚ™¥ éÕå#3.#3ÕV†›}Øwâ|¬K$xjÍÍ­£-¥ë„`pÐcM"á´³[f7·ªˆ1*›;aX¬‚À”)ñ)óšçy! Á#3Gãxn$àOÌô7ÀB½æœqµh˜˜v´àˆàƒ¯Š`f=Ùìi¬é©´ŽìI#.dûÏ'Y}Ì\ó'±íÓÇ׎•ÑïADV ÊÛ|ÎXWL…}2 ,-tºÉ†y•¶™ Âc›dhU6›âiu«*ÈLJnoY!¡&s•Y´lÚÐ=PÖc"«,¹] €ŽZ¦(ÃÔš"X¼0÷^Þ/”Õ”eŸt¥,E¨l…6d÷Þ °)EÝ‘wih4û(ÄØ=Dœ(ác(3(Vݹ„ò‰G¸t£ñÓÎXi#9i8)DT @Æ•¥ Á¦ 4,…†ÄT‹œ,„ŠHF-Šh4 4 "b 6b ÈK(²’àˆ„æ$€˜.3Hf"¶B¦Ÿ×;@~§‡‰òž¼,$côý7¨uKheýd3‚áSGÞv#3ÞåõѲ5ê×¥§x×Û䢌߮/8J!cO„Ù10™=µ…«ÄýÐh<™1êÂ}ª7ˆŽj¥2†Û,’ |¬âé= ©ñƧ‘'q7èпíôu&ôqcg1rpåFR ÕÛD×'Ž1¼Ì'ÈÖˆžŸ®cÍ—48˜ÙBÓEID!#Õ‹@kí¯ËIbB(ÈŠ³20¢7‚†iK ýD #* H0@$6¶‡Ê”P²2³–Ä'ÄR«G#dR&ÒªŽê¼t¨Þ*»+nWMªKWxè±mŠÞu˦®ÛnW5;s!˶¼ZŠxf¤ØÚFÌÉ©SnqÝ·wjÅ© @Š4ˆ%¢…ˆ*B5)©·^yæ¤b¨£U^5£U‚Ž6!bX”Ÿ6…߃бÒ„rE%õâœÏvYè*§#*…Z@4# ¨1U#9‰B”iŠ¬­#* W¦H„!H—#*¤"ŠîÙR_-®¶»Ü´5x„æµÖ½¶¼™D0 BÂè'ÁçË#3b³t±WKµeu¯fÑ[¬kRšXÛ"úzåQJ”UŠ˜˜ÊiFŠ¢¨,m3EFET[YKAcF¦Z6J’̦ŒÉ’mMB6¦ËHÆƶÍ^v«£}7E®4…«è¿GÝìÉíÐÒ_ÙQˆ¨]qÅÅR#$‚€*0E\œþ£Ã†GóöcÕô/ZóK'ÓöRŸÛôBžÈ¡ïK±Ñ]ì¶÷hÇ” qoNb ©EÊ!(ÉL­ð72ù·¯6hÛhúæ·àU·#9ªO³«¨-oYÕ[Nîκ×vŠZÛ˜¨¶Ö)-¹®\Û:º–Škm6ÖW¦ìÍebŒU^yµæ¯6n¾«?å!šnÅĘrPúJ||é*†S ‘y ¢‚éC#*’@Œ#3äGBÈBÅÛtFÒõR%F¢¡I#*£"2#3< *…†IF㳧ŠÛ H&h9Þå6€P$51&=‡ŒÂ­ˆM' =aO¾íO€êùòkÑ6øÅžX,p\Ÿ9˜ýµæQ@…ÏÎòÍÞ©%¨‹ ôf› £iä#ƒaêªäÎ;V4i²0¦f3Ÿ}–8ØÆ2»™&š„Ä#Ð~ HÍ’ƒ9S†Ê8„4Ã2[85Ñæ糶ê]§&d™9ÐÝ&Íyñ¬–½<¼/aI¯/ å4C¡“6NØÚ •¿²•c‰Ã#9Ùa#9¶C™>âºK±²ù;Þ7B˜¶—’U†hĘȞdqqÛ\Œ´šf[¡¥–•ˆ~‰ášÑ¶ŸUÙõ¥Ì8hðuKEdsA–„ñ/qÁ”²a¤K»ÝïxèP‚ÁWøIÝB±‰½j÷(…!Í›#*½Ç’Y È<ùãMŠÐ>·qºõYÔªlœ¬¶z±´ýþT?Þ¬xà©LU‹}&e”ꕵR±Cۤ؞F”QéCìPüØÞANQO¦°‰IklZS-¾4¾¦ÚÝ6È#þ²1ý¤\¯IÝ\ã ‹rh¶·’{:²j¶-¨Ú¹Uˆ"Ÿ)ŠÇ´¼ŸÞÜ:×.HËóú¢Š dÄ@¾:lß" ð!ì[WÓbŒbÄ…î#r S„U‰AK1kR£kc2µyyÖÜÕËy5­¼]SD#3 ™>Ò©Y ”0š¶1)4Ò”pHÂ¥8 †lȘ0bü+m궷ÎJ¶Ù’Q’Ú±Ÿ$”ÀE‘"6L•Š4ÐÄFÆ”’Ë(§½#Š%XÂàE„A2##*d8‰3šÆ˜¹h¦3QŽ±’PFØvƵ+’®™CP–¨9m%Ç- X¢ˆa‰…#9’Q%TB…B…b±‹Ä@æ­ ÂÁX£Øn#3¶´˜ÏéرvÆÌÛ¶›§™…ØrŒc1©-FíÚ|8g¿D#3s!Ìæ¯P*¡oªZµFÛWá¼&"U½X;¸#*—"Çóèx÷å Ú}$ mö«ëÿU:d\Ÿ¿#3‡û?Œ>9 Qк0ý-~{Q“ó{Á ò8Øý_ã ¢/3¤×I:3^®'"#G¾K9§ŸÃ}ÏÉ“OŽ°§~Xè9h¡œª˜SDò‡ÉÖudlF…”Aù2îË—ŒÉ#m¾öv> ª&ƒ„—=]5,ŠùÙ—PÝÛ!Ä{B"bÚ±L„;ÌìiŒâ#9Cg˜l°õYk‡[†–„9%!† ÌÙ?»PÌ}Ú ²$¨ÚßBŠÈ»"•Pó)XŠ0RHˆ,ÃÑÙ{‹#3—4Ísl,®@)x¿ˆ@ipæ׫«^ùçÝñî r¯îNI!.Vsó~‰­NÇ Úµ¤…5QÃ¥ÕÛXÓ*ÊÁ-Ÿ°ýÍ ÐS³›s›I '\Õ](Uݶ[«»«ê×Lû`¥® %Þü`*‘B¢ÔQÈíLgÑû,ø]x"eá MTI@¬ŒS)Œžð³aéÚ¾q‘ hͧm,”hƒiŠ±m¡ƒd;¼^B¢RŒ¼®dQRÒÈ–DFÂT©Z/×YjM(¤ØÁãpØŒ%͹\¶æî;¦óyv㮺ŒÇ:båwvérñoM±Êl·“ÌÛ«—UÍfX°íÞZ¦ÛE‘çmQªé¹[¥[&Õ)ck¬S›вm&ÛÇtnœµÝ™Ó\‘©RîÝ*ë.u–£EËj-ufÍ@ˆ#*”u›-ˆ»ÚK(¡íO\ý·wA܉G·«Š” ˆ©ïÓÕFÄ=#*w ÿoxxBðQ`Äj€ ”#9's,ˆª/½SÉÕ˜€—ïœg¹{„r ƒp}E á< È¡‚-ÒzãGŒ'°5#3~ʶydÓömôm#9§áÅ?WpsÜužä,¨ŸÖAW€©&³0EZŒÌͲù¯¿D´¨¤B#9e¥èP¨ lm hС-O] ?ï%;!" D"F*#9ø¾ÿçú¼­{¶ÚŠÛF¤*5RmbÚÙJµ#9ZEµïD$GÖ}Œ ÐIä!‰sØÉ®mÒ.îÚœîë©ÝK5Š&îÛy6¼W’Sðy»Ê\†04À"îF÷2BXq"U‹†“jrûý¥äSF ÑZ…ÐŒ„JzWJL“4¾#9Û{).õ(F’(ðB0%NH…ô¦0mdˆ£^—¥ZÞdj6ÚÔR4¤]+làLˆQb1 HG:#3píŸÁÁs  â‘~”A¶•éãM‰þθ&wÊå(ˆ8`‰0Œb±J!ƒâï›}`6ÀBu©œ^#9*Æ ²,P"ŒH„ˆ¥*kl©M´Ú¦Ú¦Ô‘`à£Õ¿ ùš š˜Š#˜ŽŽÙTºí­Õ³cM¦LÕPD‘NvWÔy°#‚R;§ù¶¯§áiÛWdæM¤¬˜¨™ºš´­FkCfklÙ%&åÃÐA?äH:dmµ2vÁÒ-ivˆ{b AN[®YGQtmý©^Ó¼(jI&ðÔ£×ñç~FÔsÖY¯MÕ;¾äݾzÏÙ’Õ‡åd`?@25?Ib›Õú´¯Ñ~™zAw,­’°1tjç/PDŠ!»v¸ KYÇ4-Rîµ.#MGÈÆФŠBHN#3ÄáãnµÃèrk¦Òèy ?…ò#3…ø€{ð#ây3^ž`’¤³Ç,pÔДž(]£@P²C !R ÇY%¢ƒ`ÐQ8ð?S©µ–äl„M7±A‚Mí Þj½—­k%Ÿ×¼^mÒ·5ºIW(ÇX&Òm-Suƒf3R±BWA*0Ö 1˜3»eCf,uYhXKE”†ˆá;رfR#*„†c2‚)x*·"²2iGðT I$–ôL“$â+‚«ââOoµá`ªi˜Æg#*üÁ“”!tTÎ P@¨{i°àê<.ñZ™d•ëô#9Ð4i˜& ™¥B’’?Öq›‘`Ž²˜UÁ¢ö0Z KJ) (£t¡D*H#3Ž¡õd¦#3)#CSv‰³ß 'b®ÄÔ²qãÀ0 PÓc¦aÖœ:ʉ AÖÁð…!é*þ§“É~5ªÈ°¨ˆHÊD+uÓv b£•ˆ $5Aˆ~Ö»´·Kº©Ú¸ÕKRÕ²ËtéwUõ@#ÐýTÊ+!"@ê*©%¥¦‚Tƒj"Ùƒdj BÐB@‘NtRYÕ‰ŠÒŒÑ0u%•3OBsp`FCÚTþÂB æç¹ø[½BÔ9²R•‰‹h„ µ.“Œþü4øJ¾,6¸üîªtbúY [Ö´¹Úæ#3jk±Œx»¨K&IŽ#9’F˜WY£Æ¦cmÙ!+¡ž*ÅþæClÒÐV†ÇÓû‘¯˼œ£U#9²œª¶Û#9÷i…|þ£yÒ‡Kʇ]tÂ=¢wЙ­Ó(P6~ê½c€e¤4J‚*;‹lP‹C-Ü7·ý#3)– µ!#9·S ˆ˜ÝKS©#¤5d>ÖsãÏ™Tn:Ìå¶c5J3¶Mr¾3w’DÈ™C#3¢ë™VfÀÄZ¸”™Á\)¢#*c0²cFŒˆ–±óÌÓ¹ñOPà[{Ça†ç¯¿CœCïü#3æ¬û4 Q†%EhÅÁ&v¯W9ËeN¶Ì´}ô®ª$sëûUOc¬^ÙÏ©‰{PC˜Z*›ÊI†‡Ý™Ù$p°ÝY”T —VTKñW¡7ßÖõûã䘡¾ÁYµmÂVÐ…½Ç9Ƈ©vù¦èîΘӗ@+ÔÍ7Ë7]Ùή²»Æ½+™ôȬ„Ž]R‘ãmÖAŒe¶‡“¨!ˆˆfŒG3C&4Ä0²e’i5Œjš]¦Ù ‹æuLùKæñërûvUzZËÚôç(hŒ¬n—ŠºÞ8ëo+€LÍhMO#9äx=g–¬éO4½{Ö“Í€[ÉÚþ·róͯ]} #=ðÁô†ÿ2#3žàæ°¾¦w e{[¦+š÷oaNP4qL×n#>Ò»<œ o*ÆŽ›¼¼¨¿‡Ð(‘KÕáG!P¢uÃb¸¬®¤–µ¹ÞŽœt¦#3„©8ª!=ŸdHû±œ!³Òá?„Ä<‡«ûúTã-¯ÛWMC·Œ‚^'YŠtzÇ$GFá›h/©:²r0‘G2™f•šØ²eÑ,û\Œˆ„²»©Ñ#3¤9S]†³#&ß¡Ä$‡Hâ…fõ£(*ºñ%ô´˜*´&¹h…(6šTáÕ×Õ»LÑoÞQnôÂ+µ –p@õí²5›ŒŽŒEÅ«¡{Hy¦ˆíˆuçII#*ÜAm¶‚äËïÏ^¨"Ó2¡ðÙÿ3Ç‚í°ZK@„Öú–K†CçÜTæ P.ƒ##zaÐ:Œ#3¹Üs§—.ÜDØ&É‘«iÉÉîªMŠ¶âÝ~öý¹Ï÷V§ÔÃÅ&ÊÒËö°?}­{'RKd,“Y‘û¾ mvüÐ#¨ó¸×èzQì¶ß²^‡+ºì›l¢AA‰cB!av¿gc[¨2¶ÊåqÜÝáñœ-ë˜Ý~×æ?”“™žÈi·!òò¡ÞGf¹¥MVy½íŒaÞŠáæ(Q¦[%öVŦEï(.ü´çÜË+Žc8c#ZmŠüCA#3§˜oagn±Å˜#9íƒ2s×çGQg<‡3ŠÐ†1#*^©{R²Ü] i!P±f$!.Z¹ëã8­C`Xª–™éŠ¬5‡‘?ŒºÇ…¶è)»¡Ò såÎkÇg´§u ÎÒKMÓß}#3«ÕFz\$ïa.õð§T%3hŸ†IäÊÅe²:|4gTédð†Š¥ó5‡#3h6ÅrêŸ6ÐsE*»Ï_?w\nÂ:õØ–oØ&‡oRáÓ:]dŒÝÚHõ…þ0úA¨V#3ÃÄ‚Š’H"È‘R@¡ß¼µ\#*Ú#ƒÝã"¤{+¼û«ÒzS!™›(q;"†ú8±ŽÎøìÇÚ{Ó¶\@>G¤ÞÃ`[ˆxÏqÙ ª:ìØ[®§¬ìæ®6óG—Ûòèîï6…“ Ç€xÑ戩×e[i4È#*±AÚÕµnÎbZÞã´Us‘F¾çó@ˆ®…ØR,*~ƒ!ØIÌ9ÉðXD`¡µ ;èTUI¾?Ž¾Î ]½ÇS±{¹"¡îèNãBgŹîºëìçÓn‹ZQötÓ™Ó•gö‹Êº ;R1!2ÞO•±÷G[kÝV6¶“Rk¶Eµ6¦Åƒ …A@jÎÃàpÄ·•[·f~‡†|‰ä!ö@oÌ7­6š•VmB#*Æ1XH áq‹ZñçúßÑífVREë«ë)¤ HÚüG>»º´Õ}T±@\æ?û¼ƒ$E#*(©Ù"Aš@çgãBdn 1×ñ?ÊxšîŽéÝP®’81žÆßå¾úhÖf}Ž¬ÊP¦~ÖÎx_O˜y#3Çé±|QAºº_MBÀg)„5ÄÖ5að‹vè_¢t‰ÑúkK¼í÷Nqô5gvó*cÝÏ•¿ÆÿV½W¯À Iý¿ÓÄç%k‹-#9HW„1÷øàgï~‹·KœèÚÚŠ¬ìØ"¯s oÀo¸2ƒ2A'2Ñ&­2ç {0U¹ˆÉfRÕ ¦Ú©ýeVä6z#o#3¬?<‡'è‰þ¬ü¯ðõBôT¢RBýÔÙ„ªt#*5‰.–%õêï#3´]<Ôõñê,zoXʪqÁ„Ä:oÁ#*¼SÝTn¾~·Œ[5#*óóô-ci>碪l\TA‰pþ|›¨ëmq·±‡–i#9A¥ˆìÀˆÓ7 ¶5! ˜PT~]VG2ê›Rd€òSÙ‘§“¯ì¯×¤ w2UCšä0»õ\E`,Ò#99ön«-rÏ]3I1Ÿ–ÖÕS % (È£€‚ëD¢žùšLÁU U#9Q­¬2¢Ò˜B*4†ºaú(!c?F]L(u†pð¶_©Þ bB’Y1#œí‚ùž?#3_ªÕ2î­niäæNW5wOZíT„kµ6Íd­,ªm)Z†Âztç`guo`éÏG©tXºqð ¸óùÃ-E ²Êš´V*,m_gí|Ûפû?/‡™#*›FeRDQ˜ 4PJmQ˜„˜Ñ”b#JTŒ›B“&Ê‘‘PTEŒT‡ã'./·<`Hw¿zñlI#À‡®/ÃëÎ}Yã¨ø[åÍ®ÇKÀÚqÇ …N†aÂå6"´Æ¢3…bæñÎF&FŠ@8$jBa~´KW‰úÉè°)@†4*TÚ}¢—^Y¶cœL TB½•"‘©Uœ:åëJÞ|ó“õúröÑäÎL¢u½¤ÄCmáœLÆô¸_ŽmtÒjªrùº¢“ÓrzÑ9d÷ê9pbj6›·¤ëª]¤ÙêA0ã1“Ó¾YpÔ ¯„¥<ó°~'êøwb¡ÊÓ•Mi9ƒ3>iúà kò¼æzÃV6›\’r™¾¸Õ$‡îB,™gôÿTï„;=¾$#9ƒ´š|´ Ÿ©$#3²Ø•Ld§—ƒ3›su6z·Ú¯7“aoI‰¤6#*Ø‘#3Rk$‘™#*r#*ÑÔZ¹gu¹ ×-WkºK»pÆAcš,£r$”M#*FÇ#3VlT¨™C¼B¤Â j˜R+ % aKÀP¾(#9€x)[âRƒ PI‘ž¦º„¸Õ*ÉDaŒ#934–ÔjŠÉm3kÆÜ2 ŒNAF#*Dg.{ã­¢¹ÑivfP2Ó}® S¥ËH"àa8=Mu#3¥Ãƶî'dȬñ‘Tða0dÄÑsš"ÿ=0¯Øý£/S…O<YciŒâÓXÌe@„#9ŽD3Îrz#U%Ÿ!×\"oÛÈc6ÐHÐÚ [y!³[HÒm<Š°^–¶lÑQlâ8…iF4"´€ÓoU˜âÔY Ç`BIã¼Ûw6QuÛx¶úƒy$D€GOFÑ*1±,¥EI&” ÂÃ÷’šhU´TFÓ8äL‚XË-µ4›QÙOlx‰Fá¥kM`Ù "Pi–eCbzp(ÔU–Z«N”—*vaeu¼™¶TâК ”uH£© am—v"6#9E€¤¶)e#3•-æhf5ƒ ¡i##«•5¡°hÓVîlÎ,sw¤Ò±DÜ`åE\ÝUÉ.Ö($MI…)äM:mâÛ2ã[Y½,÷AŒÙ¢Nl^„rÔØÆaº7Žm¸7ÎR•‚­;#U ÌËBÆI†@”°¤È¨Ô©xMô†a§¥„]°øò²Ž£EaVûmf.†ª]A `ÚêÅlIòj¸¸‡¢õ#3kÊéf,ŠF4mE“ÆàÍ1ÂfÍጒ.òkRPn r¨ãnbZ@Á<(Ó„}2 #9ñ#3/)ÂTp`V¸º£Ìå81`KV“Œ*Ù#*Øʆ&ðX¨\Ñ@»¢ ˜lh&¤bŠf³)i5!”býßZ(Üï»Ds¢ÆaQ»øæðÍÍß'x­‹^J*Njù\3Š´…2˜*ÌëPÈÉ‘“*È¡–ÈÃM3dUŠHÂ’1†.¤ P˜ãI”…hU4‡"1A‚Æî$õTPlŸ+§ÁlUò70¨méU‰DK‰  A³¡ˆØ¡)‘ v2Y¼R·¦(.ùÚ3DÁÛ0i½C¥P:'~ 3dY²~¬5zN#9fÂÀ ÃMˆgFSE AjãÜÊ+#3<ÆàÖé1ô4PQñ'¢F¸h5x#9Jß>fU¨ÄÙµrr}N%nÍ$1Ô†¤2#9­œÏÒÊ T¼ñ{ÔÏ%¾» VÊ1kÙ9cSÃ\'·Í& ÎMcVË`¦DM1ž#3R qbérîâ44hf•)W’ a©rÆ#9JÂè6(@ ŒK˜ `…#9@脱%(Ȭo i+ua#*‘IÉAÂÓGà›"R?ŽðèâÄ»‹˜×xîpÝݼOçùÞ]1ª2mw®®–ýÞ¸ž®GtîM£¾[áo}U–¥(Ëj6ۦͦh–Lš·Æµýt»È¶6‹¨‡â=ªRŸµL/AŒ• ”)š‹–”_Çõðê  &QDb-DD$Ã8Ö6>m#*.‡íÞ¯ïd!~M@Zéò„:þ'wÂõmóUùFÖ’¶¤´mF­1X Q (ïH¡rÚé{9"{ªT)€vº÷ÆBsuÓ볌 4¨,Šà¢‚0‹'ÛíaÔbsËÌQ‚\¡¤Ã]Øi ö`2;#9É#9¤þ&,²4Ì]Ý¢"µÕÚÛ{kË¥‡H™BC=*B UA°Êchvµ@b˃¥05ª•6b…1ð`OØ¥—uaµ75ݘ°Cd¡—¾`T"T¡ óZý†ß4Îæc³”ü6ÌÃ0½®L6ÒfF,MŒK³¼–5Â^4çGÛfºò·†·ì tR`6ø¼ævRc’p‘dY³ÈÕÇ~@èH~-vbŦ/‚µ‘µßf‘ˆà'Òær}û•N¹ÛX@Šx#3¢ÀäMÇI› #3p`•²Ò÷1J*,~³WçZ½ká¼g²Fƹü¬«B‹ã#êoN#3‰&â}“ ÊW5T†%ÛQa?6³ÈßçHœŽ°LØl,‘d‹$Bkm¿ñAÀ®ÈØ×x… ­’.í¸Ú^ß·åx±kÚslk&¬[Ù­»n]ÝUƒk›bرÊånš¬mt­Ö6æÒ[\¶Kræ«rÓ»Ù®EF¬›FÑŒQQ\¼YÝ­ ‡ë"Ú‰ˆN˜YÉ/{†£´‹¤Y¿ ªL#–g¶{M2ÀÃë!óc¬>&#*˜W"-Œé©"|U¢튫g±>Œ€Í"†T˜`ðîáÆ«§ãøhù›iz]ÕD@>¨¼Õ_x ÌD3ûÀøˆ¨t fš¯ÂOô‘%¡L+ D6¼6&À$ÂÔû{éY¸ÑÒM û²,ž) T´¢2#3JòV#*ž¾š KˆÅcO™`#3â †#*£ ¡"( " X6Úé6 J¤×ßú*½õ½U#9\Ä»q ½EEå* ×H*4–É-U%µ’ج2¬ci&V5YK6ÓV¤Eä<š%‚h¢; Ÿõ §±:5üµHzªƒ¶ÜÊ1jî í3ÄsÄú#9Ô*G+æá}qƒf-»™íöM³!­j°vô€õ‘€EJ^•TT_ ™Àð_ñ#*$‚H1"$*°Ü›[fîÉNï2¾ª:¨zN¡›#*öACtE$„H(”úU#9¿²¥š¦fÉ$¥ ´²FZ4›hmIFÔT¥&II+ÕX‹j5lVÔmµ-+LÕ-d‘d€ %ü¦=öÛ‘¹ ƒØ:ÖdÆ,*Á¸ëAÊäH‡ÑpÂÁ¦Ól#ʲqÒ9©z›Ó^g¯uW•qØ0.5QD%DJƒ$‚®¦™+!&#9Š16‡ cH’² ’ªÂD*FÁÑ‚ÄC!DŠF$ƈ£(hˆ…AE@ ‹]†…ÉE$DZC0 ö~Ìïp‚#ŽúRÌ©â˧u™i®îÓ»1pí׆ðh/TÄ[D#9#*EX‚ØÅ5´*PQÚ"…àî0ŠøXÞ`!0¦ÏÞ:vɶ§³©·ÝÝŸUisËEª)^ÈI R AO€FvþÌ™B‹>)Ý}Ë…L)£¶ÏÔÝaqöùUU O¾ÙxM÷â-È“ØeåÄ0#@ð¿1*!HÕ8>ïú˺Ì{kBÆÓ³D#35s¦¢쪵¥#3AÀ¼6=éÉ;TïçiL$€NæºbáÚñ»ÍÛ¦»I¼²êT¦f¾ÅwªÕÍFª£kZŠ\‹W]z­æÞJß}~U¤Cøà–Çñ#ö†¿*^þðÿKC"Ì‘Ï$ýÝuÓ³d€¢”}Ÿ«{Öód^îÅAö(V‚á-‰#w$µÎÑ÷ÿ¢Qú·˜Þ߈†…kI›K4ë³÷EuÆý*5Þ.j¯ÂMÛŽ#çüë-yÉ¥ÈEtÉÔ°¼½ëbÁ ¦F2V¬Jk<úÕËðÐó;ys­öá™ c'ë²[+ñ#3™,Ž¯ë{íÈÚ8ô ÷.#3g¢ ’°ýhpµÊt¡;?M‘Ï‹³ß £‹pPÎ#ýͪëÞ!s.µ#í{KMŒÁ˜Ëí¾e ’ _ºC{ÒTQ¸¨7[ƒ÷H0™rõ^|}½JjáÇo|÷:q£]ú?EJ³’øqš^9dƒ#3WRµ†§çnÚIˆ’§A#9›lEÃPG-⛲ ”µT¼-§Ò?\u‡Æ3,ÊÝž]º—œl¨^7/»Žlö‰„xŽ_¿¯n3Ý$"“QòNÁ v˜¨Þ¹’˜ÇCµíƒÐÛhòÎ#3æde3ÞË~óžž%Í£[VOŠpWq}&‚‘Î7ÚÞÚ1lÖ2a$3·âF¾-¯Mo²'#íïðíÙŠ#\Ã4ÎŽÔªN)nhÀf­UbURiÈæyʪÍÌ-g.Ð$õá¾Pt±ÃcZbiœŒ$Án Ç„rmLÅ1:,ãö7ÜÞF›8²ÕÊ“lÆNÕ6!ƒZ8œJȘzùFÍá†Û§gýÉ–g›Ñßn-£QZÚ¢Ö¢)Ù··ŒÃëÂâÑÝmÒvlÏ9žwÿ[jôÛ#9w£Ž¼¥9ZèQÒsr`›x#3æš9Ž”IÆŸD$®÷ãXðÖ³&9’D$þ3¡P?Fqqi9Å 8ã„cm)uU¡wµ:幩ëQëjPíwŒßHÊÄÉÖŒž¥"±évw|&6ÒÚ[+ôó>/9ôÌWW<¶u¯QMt-Í¢àÅã‰)rÇn°nï;šÝÚWGßïÑ%¿ŒÌŽî'öî÷çëŒ)®ÒéuqÕ–ù–fzx´“‘éØñu‰tY[ æê{ÖågÊsæþ¾Ý6ï¶ xpxÛ–qØwb,ž‹Ž&ìm’»BÂÆ6ëv3„ÈƬ‰bdÞel1™×s\ì7Â#3 ¤a{NFÖ(Ga̱&Ãu%½…„ÜéåNÌ=xrO“]´28r…†–ÛÖ£»Ç#3q²€Jº“˜P÷l“§œôßcfðqóÑQ³>!¹ÅJf Åy³.ÎzÇUãŒÅÒbòø¢á°0Í@ïFå¹+…˜¸àÀP(Úy%á[pêÚa§;:6c86ySÊÉŽ|¯À“›Àø¿Lœ(…¸Ô¡ELÔÓ¿ã…‚ŒR<‘nνk¡²{»TÂõâѼ¥XÏw!!„›F}NŒ4ËYjXw"ZA£Ì0ªtà´0¥û}ºˆ6+hVÂa¡˜2pwç`xn’ýU'—ä=7…ÂÀmëh¬P½pë6¹s °#3YC¹`´z­ÜM ´sgNÍÊH’FtÂ"Gt†!øª†SÄÙ@õÒ…P„XET#„µ ÑÀá lAÈ-ÓƼûwöçžý–)iæR:Ë·H#*:Ï‹Œ·Èr•:´NËCU49áxÅ.3X("‰{škŽ4pÑ&WQ–ÑÒà·20ªÕé7XØkg(Qùj­}’B(pI]ÍAB*Úh–¬àÉÄ9û¼øÏ3Áò÷–ËÀÎÒ¢d»v¬œ%†Y6’óEAcâûE—²ëD\{—K±Ño?)ºÔ–:Ä©S8D­fž·Æ‹t#aò[®õÀtã®û¶ýv™ß¥ÂZ~¨vôžóÒÞM¸Ž³Ù˧=#ª¥¥'W—¿X梄QX.±ó7sDÓ‘¿™¦rÅOÛ\âiíˆÆÈií×dqÎn³[Ó4o#3Ìœu3ê6Q¬IíƒÀPP³<–C Åv í2`•º[¯#9‘WUIˆjù¹tŽ½;ÈJ‡šu„ÌÄ„°„Q‰cgh…?4u¯=úxË_+Cšæ"î9¦­íg#3’›½áÝÔ>ºž<”o–|­ˆO—vØØbÉ"êÅ,ž|¶´¤ :woÞ%¶‹ÍÃõwÞáy(©âX” Óf„·Ó¥Y­D“#›á÷—1n`C‰Ó4.8zØ{†R±¯­Úȧ¢ÇÄQŽ™hÎÝŠÕ¬k¿^Z»7AÐ+Þ½½17|¸ÎÍ\m¿4‡ã¡-&z¬x¹à‰k1ƒ®Ýƒe—tºíÛLݹÁÆšp.¼\·G2v3º`TÞ+匂â4Bä¸HH j¸À*QË’«`Íl]©¼]Íq^éoËæÛÌCø—àó¯6w\<»ŽõSäá´¸„¼dw­¼›ÊqgfOˆ…‹hw^;¹ÕóÂ{…þÕâè:ôàå¸åmC£t'{FÕªÆyMíÙì”ÐäJt‰ L#3X–š0U}fºm=œ]°Öˆt)oHʶØ^¨Ë:9å(j¸Höâõœ*gpxÎâÄX9rLÀb¡¡5‚»`]MË+!¢çêë*ÏïÐÑósƒò;``Kº(àû8PÌ‚f¤*Ót}»Æ©1Áã#3Ágžã¸r§=â^â:nDè0\HCLl\ºx%ÜÍÁC#9\Ù~N.Û0Þ4k(2` ðnú¥Ûp^ŒHA „Ìã5E1N岩æ,«¼T*›rQÔ¶žÎ&t‡\‹=ô«I¶çWQ¨#3J0ˆYN “\#9#3X…‡ð,6¬éRIš)â#1dœª=‘‚+¡Ñ]ñ;ðî:›ª`‚çMÐ6cú3(°xl@>#kZ®·&@’d@‰r ¯`#*5 Yé¾<å%ÜoVffE.)ô-äB hAvc~%ÿË“7¿¼¬7ÖEç k÷PiG§Q ¦Ú²ÌI©mˆ,E:´2#Xú{Ê#3¡ï{#¶~gO"hà"^HuûÃ޽Űt!ŸQñ#9‰yh-J©$¢vqêæV ùõUîl6^=0#99qö÷C—jDNÞéÞ¨DbŸÐ;Ždìðptã>©[Ôb-‰³_ªáXØÕ~vü伫Q#!fÍã3[¬"Ù#3#3½j}öhͧQ€ÛJ3 +IZ6[ˆfá hȧ˜Ð±Æ«@˜µx«ÆòNíȵ‹Å×VópTJˆX¼UKE#9€‡tÄFÑ#*ƒk¬m­éZ+[•­Íl®›f°„;3)DQµ¼#3Ái´Ö¨±Q2‚ Æ”TE#9Š2•(#Ð ÙÄxç®9_Lü͇;[\’Éq,ÀÆ¡ûxò–.]´3©s*H+#7ѾHÂüœîzW^*ä]²#*ÅQOT‘E$¢¢6’@Ô`(Ùkú‘™‹m:nàåik\Ÿ|3_eÖ%?æ3¨jrããr4ð¶=t7½rÚjW´fðG!E²n¨)dĆ\$j<1#3˜íܸ1LÔ­Æ&àc±ºö2ôÔ¦™Z:ñÎÖY½ÈÍMi¢ŠµM­kTÈ7 eÇ’u°Ö¬zqsš¶VødÁbC ¸È…Æ5ª…€‹4Í«8/%`Âm¨5fȶÃ$Î’×å¾5©Ï9;7hÒÁiF1²Æõ«xlT†¨(DawV¢Tƒ ÔIŽ8ƘÑv2møœ‰Ø¡Ϫ{ý`Å")â4H}&Ä.wªžc8#3ƒlbÆSv‘UQ&IË‘¤DžïYJ ðd§°ÚoPOÕWº²±eÓœfþlÊN½ÁÚËâ©ØÏ©C_Ãbï„ï Œ’#º±zB¢H7 jû{|Áüš;x%HÎÑçéìõÕg‡‹ç™œ&·Úrk6—<×íý-?ÇÉÄãlÊ©\\¦gÍÆosé÷z¼Øz»‘¦î“»¹0ˆ‰Uhi©Q‘•Tçfy±ç—®»ÙÊräZHùÊ=@r;$ ÷yñ#35¡.U’­É0ù?Ÿ¢/__òÞ†…üø¿y‘骂$ŒBˆ4Unèä¤Ì8s!Löž}=D˜›L4b(ÜaíîXUatN£[[°ùõzsžÎÃ{Ͼ0/U¦¤õ‘x§ù5kñ9Â,ÂiñœT„=+ü#*}IûËh­E&Õ&ÑjÄZ’Û}#3Zå´¨Ô¡I¨Ñ‹XŒû—jæme©xR#9U#îK=‘~&r}¡š™^."T$ ‘()¥Hùxá’Æ,ÈyÔÍü ‰°÷.ÃB¡‡}ÃHÖŸûõvj±¢WEÖ¢Ž •ŠjHå&"(¶Ùƒ’&Áƒh¶=4¦¢åˆ, @FÑDL¥Ùz  Ámë/>I-‹C4K*¥#9ˆ•a›¨\dQJk³~6½åz)7¥Í“LbŒ¿Do[¢Žl¸<1„·wy†PÄŠÒP£‚&FEb•æêvÑ»,²{Ud¨{eàÈ&è¸%Ý¡»QµX™#*KÇ%ˆŒ¬mñkvE&bk›\Lß‹¶¸5÷ð9 ­ŸlØŒñ~œæäb•H›jfxlДa±$;œÅŽ< d=Ba-Õ$ÔÅU9DµQ!$9@dá(H°9’á9¯éd‘$’Hä ÍŠ¨_ÙÆ·É€zPSMR¸æÜRÓÔ°‘Á‡>žÍ,ÇÑ¿…ñ^üâ—©ÄAüŸ½ÜÏ»C_‹…F?¾ÃÞÑ.>‹'€Á¥þÌãôȹšB€Nžš´È“ËÀò@ ˜7'P÷ƒ²‰ª¡Ù¾å‚ã#3"Eæ£$dÔ%ív(x|:lO©‰çùß dÅgãÛ~.UoÃ[52UQJ–m¯]BûϦ‚ž³å-M2áQc¹RÈï¬õ B§ÏFøÄ à™kóú܉fÓü‰"²Î(îY!ó(¤êp­#9Cª‡‹YÆ#9HKä×¹2eºÚÜénÞ³koÕj-ÑÖº×{èG®ó¨3ÖЋÑì:lÄëóW@›T‡Ÿvû}iÔV¹(Ûé>‰Eu`Ênàø’ EY̻׳iÛŽ]ò·? 4=)8.ÐShm ø0çóHYdö•Q*…Ne×]Â{¢9¿é/ô¬£gΰäyÞ~£qNËp[Ⱦ¡’Nòɱž Ð÷sëU9å–…šñ«˜#–R ¸‹BÓû¾pwʤІ ?Z7Ot¢[¢òÂÐü~TQ¬’ Á*¦Lýè^ú¥ÄľÇêÖíDhª‰à]ø*Ì~Ÿ/­¶Ã1÷Ýb¡ Ù=ê Áøü]"±¹¬Àä4RbÃ!†:Ý•5Ýø Aèg‹šû¼Î#ß¡lµøžàâ²yxk# Ì_ÑŠ±f§€#èÙ }_~ópþk·õcÖš2@“˜®2®ÒãÏ)Jñ¬Í)„ 9¢7áËèÊdš‘œ<¼>#3êX†Òpé¸;I…bKæ~%د-CVÉߗбGŽ$§‘&—%âž ª}Tégêg”ì¨Ù¬Ú€£„1­”,±P,`¤YHmºÞôÄ”4 ¤Äm¼ÎÍ¢8!N ?õXãeÔÌm®)bi©«NâÙUcnF|pÉÎ%g:$Þ8Œ)»`&Pƒ5CHfoªŽ.õ˜‹²]p5‘r%¬²m#38Ôó 6g%Í ˜ÖÑ#3Â#*Åm@8 Š€nw?<ê™™±íàì2wvèÒ¥ñ5BY ‚eï ÃæÄñÕjz³› ;P´˜™Ü‚C1Ñ>d\4§f>ðGN°=œ÷‚#9œ"ª†õ*D`J#3ÏCøŒ†…!Qc V¶(Šm5¦l*@KÖeœ%blFR>¼óÇ ƒž“4H­3 iÚÝÊB‚2™`l•’  fﻸɶ*D@E#%…q¬•Þ§Œ›f4â p¬E †#9b0‚Ü:Åu½Æ&Æ0Ì”ÚõƒQë>~Pglg}Öàüï×H½¤g雇lÑ“!hÝñ]Êd&E±­ÀYWZLÁ-$TL O•F^WuÍm¾³úØ'eÆx‰l뛪§vëžJ”Ìâë‘ð –^zÛ~£Ñ™Y'Ç»òK!6à»EtIÃvkbR² c Ào¶•€Ë~hZøŽ–3±Ĥj axuGzÍÒ…ƒ"€jÂQ %ÂVLRELÈ#*QÓm(åÍÈÌqóECE2˜‚ã$Ö¢QJ’ÍÂœD[Xb'(¬+X«y£¶!°Z&Þâ©'X3P™:Ý–$>×*ØšG‘RÆA¾:ꘉÓRpÑc‡ÎG$)Ç^¯kTbDz0ÄnU”#8‚²¨ežbe3 ÷†Í9œ… !&ZêJNÒ>,‡}‘%±;!šÙHC;åžé"¶’ëÆ¢í3m&X ݶÛi`¦.G©"„žj`Ãó¬`±F¥¥%—Öí,•FŒÓ™Á ü¶À`Ú]öYš\“Ã#cÆò‹ÚCI¥=ðãC6@Oo]6.[d¤ìÙɈm¶*é¥Ü¡‘Šg0Ú›LêiÔâ “;Kܺ{Õ—[9ˆ[m0Zyk.eŠF«—Váz²a“c»¾lLù—çq! ÍÇ™†‹âºÍ‹…’»Emo |k­´¼Œ˜¹»3HuyÌ}÷[£ÙÎeZæoÑÉg3 é)I£ ž$:&°}zÌ¡¥Bµé¦o‰jtqåÐó‰¥Óv'#3tÝÓë‹–9X‹™7I4‰é:MKƒý'R% sjËÅ8ùrùT«5[e¬fFʈ™Î¡L£É@©Å#3ÂÝ|9Ö­…ÜðN»æšçb¹/D·–§'eRÖt]Ë‚áߊ뜢C}„F§¡É&!@ù¬Å#96Ž‰t̓ sYs=85«Ë¦•.Ë™ÖÒÐ`qÖÌ‹h·´7N&26¤T vèS±†»Úb$#gÜðâŽKžƒi’ÖtÍ‘E[8¤" ÉÕ…»0†/0ãF‘btŒhf bò6PÂ,E„*0U“l@ªÙšàÜ *ñ "‰˜#3PU r˜:wfv`ÒBBNŽ‹áF³¬Ö#â¶#3¸n9-l1½KÆÓ "eãd3ÒœQ‡49ôôü&7f›Ùç›Ëu®{k&/„¡Ù¥T°Ø!‘’ê{àl ré’bís- „´\hb‰|¸;èÛ^/9µG°¦NIÑ0}Ÿ§Ñiµi6£j#9fÊ.høëŒÌg–Ç.¹áÓ@øŠƒ„˜lÇw<‚6ò'ˬºÅ½W@vBݳL«á²_{N6`bhû˜ÝóhÁSpň…Ó™eìo-#9ˆ8¶‰IŠhæGuЩ8kK®Ï½´ázaº–ˆQ#3O.Ò0 ÊaŒ‰ŠŒlD26|ÒÍ}=¼Õ#*ÔÏZ¹(ª}v¢/è‚àHÄ»”¯m"²#*Wª§pðù«0ÅP-›4AëPè•=v³D¿nôÓ'àз‹.$¾ê¸ËåÊ‘8r°2‚Î"diZ©öÙd[ÏJôh¼­"ú$M2dïÉÚí¹ˆæ­0é»|r~miGR!ÀDNq“š€µ+ô#9˜6 ¸TÙ}©Ø¢W‘ÈÛxÃnhú÷<¬íf³–˜ØÚMêÝëõJi‡°E}kë¯ê¨#*¾Ú2ãÅøŸ59p‘2¬Î›ìÚǹ|?$@Ýd7äåÒ|tÈ€Š'½Bi’‰UJÉÎ PÁF£E#UQH!¿ÊKåU„Í„Î%ÖFÛ Äó YX°b+iQÍ"]ç<]Ûo,Ì‚cŒŽcpD†H1U"ckl.FãŽÈPÙKJ[m´ƒ$râ‰$,"&•†ÅB Q…˜„b‹C†•€Q¡øRf«#*óLoçQ®­ø¨ð‰·8ës’ ‡ùÖ®µÏhÇ©¦i—„h¶(—:#3œ!t#*&jb¨‘è!#* k!‡éìíÏ»¿Ì DË{%³ž%¶k½ù€½TÒ0€PÙïiŒàüëÞ=n”±CY†Å¹FªÓDN‘¨#3ƒÙ‡I:f–"+‚­#3‰]’&!’˜W†ƒÜÐTFè¥0+6ÕA…rà%ò€»êæQ:\7±Í„*3ÁíÒ4ïq§ ¦æ.Ɉ›¬RÄ@çÛ ÓJ¨|=ƒO0AÇ=»°x®äÝ@‚OYÝÊhÈã¹ôлœólÑzÌŸ“(q&ü1„Ñ‚ÏÓ¶e FÚÛzLõa‘´I²í[vsPÎo4á¿37Y#"ÆHÂu…Ó7[dž=ÆT`ÆUÈW´¯±]~GJ?Ck­&É6×ë*®­D”j¥­·5RV×PÄ–´ßOZJ¤ÛT–ÑVÞók&«ÖZÏVê­«–¯SRns!PKÑ‹*ÔE[$T.B\0T‰n%RzWr/ª+"©Ù#9ˆžéžÉ»eŠB•%îQJi§ü3Ú€§£–{Žk—‰“8z\änŠÈ£D@Y`¢0&øÇOwº{ýëSêœp3@ýbÁŠ#*HˆÈ¨2#9½ßN[÷ü4ÅO.TqÙŸž*8Ûµæ…Ñ¢ñ“‰ª°x.ó­+‰‡«˜ZÜïñ-(ÊŒ_º”PàV¸Š† Æl™µ"ïÞkwW5Ú%Ï<ëI·+™.f#3c+H` ˆƒÌD‰‘·M!奴JHÊ2EVdA²–†7 ¸ %"ÇH‚%$°tª"oDd)l£VJ’)q) Bð‘N;yç5±«š¶õ-«Åm²M…,¦#9”#*”Úç0ß`@&FuH#9Ž¸rRf¢ïR€(CmÌ‹0Í-iö‚§o(õ=%z¹<Æã^¬{½¿÷ÃNpªàÖ«G@ÜëÉ2¹·\æl¤+ß}%“vŠ_,;C·©²pøµ#9Œ¤’„p(F@Äׯ#3—¦¤.ù|š,ø*,ßC¶¢è#*‚€ÄØÓÓIk} V‚z4ð›0/9ÎøâÍa`i`;‰ÁÈLHÊWò÷h£æI#3wp!ç"O8»<ˆNé–ŽuDWæ„Ḝ­cb®ºÞkJ%‚À ^·*5R¼E}]²,,u4)L/Ç+’ꜯaû¹Í ¤Î•múÑá²á#32¤ë>ªõ(zá ¨šŸdAdzÊ@XBˆJi`µUAŒ¦øC]I{÷¹%ø6>Yú“ì=)Ú/»z¶OR#99x]o'‘T‘ˆÂ ¢ZM*Y•,SÚ,ÓAU¶6³ XM–"Š›e¯ÙQU^O&Þ^\¥t­²Ê±c””Â22N“©ÕÎy'¦8±UÓ‘¦‹·¾ÈØx¨‡#êpó›Ô&ˆyˆ\¸m'W_X€ù¬Lµé»pÑID]¹µò ]>Ç!#3<9uíº•6òDOppžçßpÌŠªt"RñgÂ4Ì‚If,æà¼øÑ‘5Ál0‰©/PÅîYDX™ýN×&œ2ðFÒÒõ$HB°&+|)³áë§Èi°Z”¶Ñ5EC˜Ã³¸’Dº‰‡m-€ÃsK0‰Ý¸˜ãp$ÙIeÌÝ™ÎÈ›(5p0«†ƒ»FÎÌ Z,pt—ÂF#3À±„ABiDÈú|U{ÈíDZ²Hl´šU&”•3Ú5#‹h"(Ì1yOD®T¸JBiúœ"u´C›u”&-#9A#3¡i%6±•á"Y%p©ô3ÐÍ*Z§Ww¢*p|TȃÆþ`¶-V¦ÅðL¬‹ æìTkA¿ÁZÐÁbÌZ­aÁ´¾Ã2ƒ?S.ÉŒºJž´´,ØûL`AqÈŠB²>_Ì%‘^ î-Þ³¿© Ò]ßJª]@Wõ#9,‰Bd{ˆ@Xć³¸Áù<àÛ„; J$p“0pêîο#3Ã¦åˆ àˆXöû æ‹—p®° Cw_ýå/õ’©¢~k´¸Z§1˜#*Ž €¡q盧f»ÏöP×S¹ŽkÞ‡ #*¼~ò#3FÀÜiéXŽÒ#9”E@ÌuŠ#9ï鯢7n°zûuQ–72‰$‰ ˜ÌQ±ØÒeÝ]0’6FÌùûÌ?c»kÓÆØñç›Ï7®âÔáb£J)¤5(‰y7s\#9ò6J£Uâæ¹n"Y+»¯óÊí+“–µå-™6ýêݵ5ÌíDZE6‰y-ÛwûŽÿ E_A_mìúªy%f©l$2iôÖ4¤*/öMq0„€wù‡xx (ƒ ±QY-M¬Ñ´­¥mE¯1!=‡R|26òP $XŠ€³JFÆѤ)fJ¦Í}~£Q¾æ«ù[âiƒFÄ1j6ÊVŠÊR•[ðj¢JY%°üL0€°†¿š5%qù”ˆd\ôaO" qMñW}BFDõ@¯„¯Znë›1Mak-b±³#Œ¬T¥%²ÁDõçx¶Òm©R´¥¶¾ÿmU !€#*^Ü…gü|ô{½Ï£åü%ݤ“½_#*‚k¨qJ2{“ÔyŸNÚ˜ùæTÙrQúöàã'¸H“ ä#*z–ža¾C¨õö8 ×5G]Y³a˜•SÄõ¾ž‰-ýÑIñ¿ÃqУ#3hddŽ‰ÚÛ;Gùî„iÜbz2`Ld*¡u ¢`D%“ò@ä›Þ­}—#9Š€ÚQ$&«Ò#ª¤Ñ’­#*áTêOrÐ@$ êP”Q†k®ív)mI«›tmT¶ÒiP"BJJX4Ø HŠ˜665ÚL#9#*¿Õ”€†À‚¥#9Àm°rT§Â™ #*‡²ÖIeíØeÕ¯G]!î‰ã|Ö-¤Ÿ«êâ/nC‡£#3a•éÍ, ¸˜ñ- ~Ë ºà™«±´Ukè° 9›@Þ}È¡ð…¶ˆ.–¥8ìjW_Ðá’öèf07ÐÐöÓ{•¢wG¸8ëoEøN榒nzXŽ¤¶Ú/äDØvŹï‚‰ûÕÿb#9Xô¯É¶ûI—äã;t¢Ø¥4Ò¤Ù¶1Q‚±T›l)hß‘¶þCW’Xh¶²`ÄdT‡ùQ'O¯—}ÒÍ$#l$ ÆÈZÄŒ'­[•tO .„ª(bdÂEÑ46î(Ô,‚”§T[ç>ÈçÁwmà,’+ éeU÷f³bµ«Ê±mF5 µ(U¬Ùb6±a Fì<8÷É¿+s_,¹‡%|Ž£‡µž]-¥VY) !ˆ$þ&}I(a#*QÙyPþ|1ñ¶¼šfàn$Ú’ìÆ©!Fº)¦âºøÒÞ/´ªÔ7 ´BE«ZþG‡‚Y)¶eˆlT²‹ #¸¼b¨bsÅØÁc“üù0@4ã#9 &«Î«¦ñÖø­Û4ÍM*[Öö±¢1…ŒD‘1DÃ*¢D´Y-½š¹²¢Þnë3vfUvæí¨«¨$¶Eš·—v54JÝÝ]Ým&Ê’¥"`ÆÐØ#3¢È#9¡¢ÀŠÂD•9)V8ˆƒmF*65F€Úa"öoo."Õ)¯UÖÝMI–Š¦ ²-‰%X†Ð˜6šjËe-yÝËv»·E–2¶]4AŒ#{7‡VlzÂ`!I`íA-„2iÉ#3lÑýã^uU­ °´,XÔ_2ȨÅPL’(Ç#*ª@¦yd¨mGôi¤Ê[FjV}é2Æ ª/|˜1¦ºë’véH ƒ¡Æ(l‚›Ów*´×´Øu@êÒæeÒä]ßÊåû®¨\<¡%ØCßfÄöá;ã"Ý ¹íðÆ&òzµœXŽ3€]95òÜK‰ wkÇ<ŸÒDèfB§vL&†‚;j9}#gk‘##3wr„Ɉ^ÿ2šW\…; >½¼¢ ‘EW(¤gð¸7ש1¼\×ñVÂMN‚1U…Sp"¬¾>9˜Ú¬ˆ»¿Ãû2’_ØGAˆ¼Wí#Z¾‡O®J˺éRzk{üÑlIÀ$§#*.\H1¢7!¶dI§ßë&yÉ«ÁãÓBø´ƒÖ$-–ÈS2Lf_#9§ÆzÍÃT¡ð¹¿qÚT7ÇyÁ&5Ó"÷gétóa7VC¸@1÷è>^#,äiy¼<Ö B‘=ÑúOšQ8³yÁMÑÀº#3h-ZN¤–ÁQHXÜG`ÌiÉÕ3=©Ú&Ñ@ÑØÂ!·v¬À!Fô(3âšÒY¦‡§ºú¡Èçð©WiPd›b¢è²”Û©®›®DTbX#*ð'úQ±û/îlÅœàE¼t›~ä ¡fwrò'WwN¬åÎ6 æúÜÃiu4>sꇢI1XÅÒXÚm6uº:;“œÕºßñ¡#9%ˆã`æƒßés̪Œ´³çzÖkºj‘£'ïIrÔDVí¨²v+çV¶ómAn ”2U 0Ý9$¼Ê„q}~EmÖð\#p uð§Ç~¨)†h5¨ŒB¶”¼N&>rù¶o5Ô7„#DF)Ü觰A{ïM ز$ÚCŠQhšäsWwvV} ƒIÒc®ûõÅо/¸z¶V`"ω©ËHÙ’l?1íŽÓöÁë`¢ÏafãÈ¡ÞyÁÈj ‘¬-t<#3Ãé¶ M:ð8kPÌ&d$4kFµ¨f0†d1×ÝþØÀ‚D<‚)':n„^Í-õì÷!õ÷+rP:¼‰¶Ÿ~#*±š0€Wß”BЀ\€©ùª“Ož`YT6Sœ™o]#*#œ,Ò#* #Ï0î>ÒÒ7u?¥ýǧJ3hE/ JŒð>»Æ˜Æïá“ÈÇÕƒLÀÈAšWìŠ;âx²ÿ?èÿñÿóþ/Óÿ‡þ>?Ûÿ×ÿñÿëÿßÿ÷ÿ…º?ôü¿ñìÿßÿ~ù¿Wv¿³×ôÿìÑó|ÓÿóþŸ÷¿ÿÇ¿þß÷b?ýÿ»ÿ×ÿßïÿ¿þÏú¿îÿ‡ÃýÿòÿÿíØG£ÿç_ü;üÿýWðÿçÿgþ/ùíùü?ãøþ^|?@GéTþòä0#ë²#äÿ1ûÅ2Èžð§lC!Í«‡ûyH€ð ÔypíÈÖ`¿±þåJ_à»s1P ÇþA–ÀõìBJ¨Ša©a0ÉxýÇøôþùÝÔI I™Ÿ>·ËT©ç+§h³#*kŒ„Ä;/EPC8Õ;c"QŒùY…5˜ƒˆ²Áýöxq½…Àl(£þ\8nL‡MÅÍ£˜³›È7Û’/g°žÈ¿ñe‰ÒGnâ·‡:‘j dɇ<Ýa€Üו¦5žY”|ÔaЙ»š‘/òŒKÜÿÏOa%r›?ç=w“±þãÇû+—Öþkû8ß#ÞÔ8y.ØôøP÷pŒºRÚ¿óÃuËJ#9,KhL¤„#®ÿ9Çÿ#3\·)àÐïqñ¥ÿ²·FQ„éb`„Ès!)U‘ÊÙ™ý\]¥€ojTÔ‘#3ø¥3ËKL¢ŒÒë!TÓLÿN ÃÅ*aàÿ£qDh„SUSÂѽíã¾ÔÒ&^!Ý°#ÅB;;¦Ý4+Úˉ)cM ,‚ öÃìqíé$Tq’ma«nÑëN¨éYBÀf3A*å š–6‚ÍKÖc1„ši3–#9(~|³ad»’ ¦”é#3…-¼Þ}ÏY—ÔÅ¢ÜçDÙ°ãï2êPâcK(Þ^ñd´cUp¥ðCAZeåÊ™¯CfrvRÃe#9Ü…JcëŒÒ€„R$Z#1›\¼ß‘²ÀÌm²ÚB†$èAùËf:‹:èõOòÀ äEQa5«Ç‰Œ0²·ÔÛÅu#3¶ûºG†·[1Š‡#*ᆠ<{fÇšÎ;jÿÜ_ŽyÄ?â­wÿÆ Û\]¤j×´éÁ=L,vîk5S|’bQdèŠ#9DuÊOB"aæóa ¸SÑiÈ´CB®W¤EÓ©ZZ)`A:Ì€‰%æäÿÜX'ݳFÌ°b»î4p1êÖ!Û3DE`«ÙŠXT/Çw>Ì|wjf#*s2„Œ‚k¹ß.\Ðò‰³Ä¥[¬#*º²(@AÜ%7í³eCEP1‰ ³ðd:-**È!¤$ ðø= Úé{ß6/ÿ Òݳù>²$éјÂÏ:´y¹î|4}^vÝéå ,F*0 ɘúÎí¿ý·A:˜¦§^§"ÛøVá;à‘‚Ôj0ŠI¶Ô¤Lm ÆâDж#9¢­4¦V±¬•ŒÍ$H° 35ô]µuµWÃá@¥È=±=Z<¬€éÿ¤€Ù#*/ÝTÝï)lRe'Cã(#3Ê”ˆ¡ó:þÄáìæþGþÙˆiûï‹WªþFréIP9Æf?ÚçD2¿ˆ5Ç»K®¢ì´*©ABhˆQ?=ý§$œàhei®¢N´êeêÏ6HdÓ†Æmÿè¿…#3³à|Ú(ýŸ4õ„gF9vµ¤ïjo±Aßß)*áÀ0…Lc¦e¥áÌC¥OMdq."ðñ|ù Ù-9§†´g-]ê2ÀÑ%Æ1§ D6ÍG„øÑa¨!õZáWé·9\ûÅ­Ò…tÜ44løsõV«»=Zñœë¢X)5[}¦ì±¯²Amõ5Ìlm+UÊØÆñm½(Õì­oSFµ&Å Õ^ù­rµ{|:·£Îª³v mÖå”°qpä‡71Fg©d7²‘NýÄO«›nÿ—NÀN™"˜#'@£x´Ç¹ÞmeºÌ#™†à˜R†Åxôè.1è&‹%Ǖ׋•IGP öž¯û õ_Â#9ì^4É@$fñÍR¿íûç—ÞÊ;´NhïGcÞô å ‰þæ\T=*|¶#*Ÿû`£(° @"µÚŽ[Ží›n£«\Ùª³-©™®–Ý«²Õó,“fŠK{ok[_šDH¤€ £ºwû½žÙ©é¤?ïŸh›b€¼º½0=3ÃÆQñá2Ë Ãm¶-Õ8»@×dþ4àÿVÇO•¥k:,¥'àØ‘‰ùóüÔõGýâ‚œ7þk Ñ d‘IàV¶Ú{ )"È/þþà(‚ó¿ûÆüz.½5ÿŸóLa?³ÿ¢Ž¡ûl'ÕõíÞÞþM§í šàã—QÃh³Æÿ°TPw–>?þßgû·Ô¿_¢1v]¡å¾i×gtôtý«µþ)õÂ͇…„{ýn8Aì=e…þß<Þ1ñËÿÎÁèæŸ/ÎsÙ[)‡@‰G;šëüW¤´ÑÑa´¯…NIC÷ÿÙ©7aûS öpÜÒ<‚‹´«3 ÅRÃø+ÝR?w³YžŸý¸Ñø"‰ScعBºÄŽß÷{Dx|á•@{üìÄûô‚â¦RAþ(ýÕ(ÿ…E¬àt®Þ'DS8&û5\.2Î`ÔþGøûv;hVV?›œ±7„n¼¶Æü<#Dâ¢Zò¶œÂAôúxm6xž_H8ExR€Ã¥ Âí’ ‹.BPN1`­#¡—KÃCE.PZ€Q9±Á„‘ûÿh+¸i ÿo5L{òä´yõò*†s¡é< ¸¿„µV1þ®À$û­ÖAµxØmrª»T¿P¶ËSÚ—O OØuþßÿ _ã‚ȬþÔ† úFþ´Š‡ûòÜÍù²„«/Y ?ÿ‹¹"œ(H&ãå#* #<== From c2e3b70b3764dba6d026cfa0a579f1e9503d09d5 Mon Sep 17 00:00:00 2001 From: Aydar Zarifullin Date: Sun, 9 Jun 2019 04:25:26 +0400 Subject: [PATCH 203/211] hlsdk wscript fix (#82) * hlsdk wscript fix * indentation fix --- wscript | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/wscript b/wscript index 97131abb..ede9efa4 100644 --- a/wscript +++ b/wscript @@ -7,7 +7,6 @@ from waflib import Logs import sys import os sys.path.append(os.path.realpath('scripts/waflib')) -import fwgslib VERSION = '2.4' APPNAME = 'hlsdk-xash3d' @@ -89,50 +88,50 @@ def configure(conf): linker_flags = { 'common': { - 'msvc': ['/DEBUG'], # always create PDB, doesn't affect result binaries - 'gcc': ['-Wl,--no-undefined'] + 'msvc': ['/DEBUG'], # always create PDB, doesn't affect result binaries + 'gcc': ['-Wl,--no-undefined'] }, 'sanitize': { - 'gcc': ['-fsanitize=undefined', '-fsanitize=address'], + 'gcc': ['-fsanitize=undefined', '-fsanitize=address'], } } compiler_c_cxx_flags = { 'common': { - 'msvc': ['/D_USING_V110_SDK71_', '/Zi', '/FS'], + 'msvc': ['/D_USING_V110_SDK71_', '/Zi', '/FS'], 'clang': ['-g', '-gdwarf-2'], - 'gcc': ['-g', '-Werror=implicit-function-declaration', '-fdiagnostics-color=always'] + 'gcc': ['-g', '-Werror=implicit-function-declaration', '-fdiagnostics-color=always'] }, 'fast': { - 'msvc': ['/O2', '/Oy'], #todo: check /GL /LTCG - 'gcc': ['-Ofast', '-march=native', '-funsafe-math-optimizations', '-funsafe-loop-optimizations', '-fomit-frame-pointer'], + 'msvc': ['/O2', '/Oy'], #todo: check /GL /LTCG + 'gcc': ['-Ofast', '-march=native', '-funsafe-math-optimizations', '-funsafe-loop-optimizations', '-fomit-frame-pointer'], 'default': ['-O3'] }, 'release': { - 'msvc': ['/O2'], + 'msvc': ['/O2'], 'default': ['-O3'] }, 'debug': { - 'msvc': ['/O1'], - 'gcc': ['-Og'], + 'msvc': ['/O1'], + 'gcc': ['-Og'], 'default': ['-O1'] }, 'sanitize': { - 'msvc': ['/Od', '/RTC1'], - 'gcc': ['-Og', '-fsanitize=undefined', '-fsanitize=address'], + 'msvc': ['/Od', '/RTC1'], + 'gcc': ['-Og', '-fsanitize=undefined', '-fsanitize=address'], 'default': ['-O1'] }, 'nooptimize': { - 'msvc': ['/Od'], + 'msvc': ['/Od'], 'default': ['-O0'] } } - conf.env.append_unique('CFLAGS', fwgslib.get_flags_by_type( + conf.env.append_unique('CFLAGS', conf.get_flags_by_type( compiler_c_cxx_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) - conf.env.append_unique('CXXFLAGS', fwgslib.get_flags_by_type( + conf.env.append_unique('CXXFLAGS', conf.get_flags_by_type( compiler_c_cxx_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) - conf.env.append_unique('LINKFLAGS', fwgslib.get_flags_by_type( + conf.env.append_unique('LINKFLAGS', conf.get_flags_by_type( linker_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC)) if conf.env.COMPILER_CC == 'msvc': @@ -144,11 +143,11 @@ def configure(conf): conf.env.append_unique('CXXFLAGS', cflags + ['-Wno-invalid-offsetof', '-fno-rtti', '-fno-exceptions']) # strip lib from pattern - if conf.env.DEST_OS in ['linux', 'darwin'] and conf.env.DEST_OS2 not in ['android']: - if conf.env.cshlib_PATTERN.startswith('lib'): - conf.env.cshlib_PATTERN = conf.env.cshlib_PATTERN[3:] - if conf.env.cxxshlib_PATTERN.startswith('lib'): - conf.env.cxxshlib_PATTERN = conf.env.cxxshlib_PATTERN[3:] + if conf.env.DEST_OS in ['linux', 'darwin'] and conf.env.DEST_OS2 not in ['android']: + if conf.env.cshlib_PATTERN.startswith('lib'): + conf.env.cshlib_PATTERN = conf.env.cshlib_PATTERN[3:] + if conf.env.cxxshlib_PATTERN.startswith('lib'): + conf.env.cxxshlib_PATTERN = conf.env.cxxshlib_PATTERN[3:] conf.env.append_unique('DEFINES', 'CLIENT_WEAPONS') From 89b312e44588930ee2a31ccb0f1c64ddc3441f5e Mon Sep 17 00:00:00 2001 From: iZarif Date: Tue, 11 Jun 2019 16:04:19 +0400 Subject: [PATCH 204/211] add waf.bat --- waf.bat | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 waf.bat diff --git a/waf.bat b/waf.bat new file mode 100644 index 00000000..dac6143c --- /dev/null +++ b/waf.bat @@ -0,0 +1,101 @@ +@echo off + +rem try fix py2 build +chcp 1252 +set PYTHONIOENCODING=UTF-8 +rem from issue #964 + +Setlocal EnableDelayedExpansion + +rem Check Windows Version +set TOKEN=tokens=3* +ver | findstr /i "5\.0\." > nul +if %ERRORLEVEL% EQU 0 SET TOKEN=tokens=3* +ver | findstr /i "5\.1\." > nul +if %ERRORLEVEL% EQU 0 SET TOKEN=tokens=3* +ver | findstr /i "5\.2\." > nul +if %ERRORLEVEL% EQU 0 SET TOKEN=tokens=3* +ver | findstr /i "6\.0\." > nul +if %ERRORLEVEL% EQU 0 SET TOKEN=tokens=2* +ver | findstr /i "6\.1\." > nul +if %ERRORLEVEL% EQU 0 SET TOKEN=tokens=2* + +rem Start calculating PYTHON and PYTHON_DIR +set PYTHON= +set PYTHON_DIR= + +Setlocal EnableDelayedExpansion + +set PYTHON_DIR_OK=FALSE +set REGPATH= + +for %%i in (3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0 2.7 2.6 2.5) do ( +for %%j in (HKCU HKLM) do ( +for %%k in (SOFTWARE\Wow6432Node SOFTWARE) do ( +for %%l in (Python\PythonCore IronPython) do ( +set REG_PYTHON_EXE=python.exe +if "%%l"=="IronPython" ( +set REG_PYTHON_EXE=ipy.exe +) + +@echo on + +set REGPATH=%%j\%%k\%%l\%%i\InstallPath +rem @echo Regpath !REGPATH! +REG QUERY "!REGPATH!" /ve 1>nul 2>nul +if !ERRORLEVEL! equ 0 ( + for /F "%TOKEN% delims= " %%A IN ('REG QUERY "!REGPATH!" /ve') do @set REG_PYTHON_DIR=%%B + if exist !REG_PYTHON_DIR! ( + IF NOT "!REG_PYTHON_DIR:~-1!"=="\" SET REG_PYTHON_DIR=!REG_PYTHON_DIR!\ + set REG_PYTHON=!REG_PYTHON_DIR!!REG_PYTHON_EXE! + rem set PYTHON_DIR_OK=TRUE + if "!PYTHON_DIR_OK!"=="FALSE" ( + set PYTHON_DIR=!REG_PYTHON_DIR! + set PYTHON=!REG_PYTHON! + set PYTHON_DIR_OK=TRUE + ) + + rem set PYTHON_DIR_OK=FALSE + rem @echo Find !REG_PYTHON! + rem goto finished + ) +) + +echo off + +) +rem for l +) +rem for k +) +rem for j +) +rem for i + + + +:finished + +Endlocal & SET PYTHON_DIR=%PYTHON_DIR% & SET PYTHON=%PYTHON% + +if "%PYTHON_DIR%" == "" ( +rem @echo No Python dir +set PYTHON=python +goto running +) + +rem @echo %PYTHON_DIR% + +if "%PYTHON%" == "" ( +rem @echo No Python +set PYTHON=python +goto running +) + +:running + +@echo Using %PYTHON% + +"%PYTHON%" -x "%~dp0waf" %* +Endlocal +exit /b %ERRORLEVEL% From 0e1aa692a393c6208647d043103df22fc4012d30 Mon Sep 17 00:00:00 2001 From: Aydar Zarifullin Date: Thu, 13 Jun 2019 00:58:48 +0400 Subject: [PATCH 205/211] replace gnu.txt with LICENSE from ValveSoftware/halflife (#84) * rename gnu.txt to LICENSE * delete LICENSE * add LICENSE from ValveSoftware/halflife --- LICENSE | 39 ++++ gnu.txt | 621 -------------------------------------------------------- 2 files changed, 39 insertions(+), 621 deletions(-) create mode 100644 LICENSE delete mode 100644 gnu.txt diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..60f4aad3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,39 @@ +Half Life 1 SDK LICENSE +====================== + +Half Life 1 SDK Copyright(c) Valve Corp. + +THIS DOCUMENT DESCRIBES A CONTRACT BETWEEN YOU AND VALVE CORPORATION ("Valve"). +PLEASE READ IT BEFORE DOWNLOADING OR USING THE HALF LIFE 1 SDK ("SDK"). BY +DOWNLOADING AND/OR USING THE HALF LIFE 1 SDK YOU ACCEPT THIS LICENSE. IF YOU DO +NOT AGREE TO THE TERMS OF THIS LICENSE PLEASE DON'T DOWNLOAD OR USE THE SDK. + +You may, free of charge, download and use the SDK to develop a modified Valve +game running on the Half-Life 1 engine. You may distribute your modified Valve +game in source and object code form, but only for free. Terms of use for Valve +games are found in the Steam Subscriber Agreement located here: +http://store.steampowered.com/subscriber_agreement/ + +You may copy, modify, and distribute the SDK and any modifications you make to +the SDK in source and object code form, but only for free. Any distribution of +this SDK must include this LICENSE file. + +Any distribution of the SDK or a substantial portion of the SDK must include +the above copyright notice and the following: + + DISCLAIMER OF WARRANTIES. THE HALF LIFE 1 SDK AND ANY OTHER MATERIAL + DOWNLOADED BY LICENSEE IS PROVIDED "AS IS". VALVE AND ITS SUPPLIERS + DISCLAIM ALL WARRANTIES WITH RESPECT TO THE SDK, EITHER EXPRESS OR IMPLIED, + INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY, + NON-INFRINGEMENT, TITLE AND FITNESS FOR A PARTICULAR PURPOSE. + + LIMITATION OF LIABILITY. IN NO EVENT SHALL VALVE OR ITS SUPPLIERS BE LIABLE + FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER + (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, + BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY + LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE ENGINE AND/OR THE + SDK, EVEN IF VALVE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +If you would like to use the SDK for a commercial purpose, please contact Valve +at sourceengine@valvesoftware.com. diff --git a/gnu.txt b/gnu.txt deleted file mode 100644 index e587591e..00000000 --- a/gnu.txt +++ /dev/null @@ -1,621 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS \ No newline at end of file From a78709ccbb8f5b2a8fda746e57409a64ee4a0c54 Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sun, 7 Jul 2019 19:03:04 +0500 Subject: [PATCH 206/211] Add a missing newline characters. --- dlls/bullsquid.cpp | 2 +- dlls/houndeye.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/bullsquid.cpp b/dlls/bullsquid.cpp index af3ab88a..8db94c25 100644 --- a/dlls/bullsquid.cpp +++ b/dlls/bullsquid.cpp @@ -398,7 +398,7 @@ BOOL CBullsquid::FValidateHintType( short sHint ) } } - ALERT( at_aiconsole, "Couldn't validate hint type" ); + ALERT( at_aiconsole, "Couldn't validate hint type\n" ); return FALSE; } diff --git a/dlls/houndeye.cpp b/dlls/houndeye.cpp index cedee258..940b68ea 100644 --- a/dlls/houndeye.cpp +++ b/dlls/houndeye.cpp @@ -155,7 +155,7 @@ BOOL CHoundeye::FValidateHintType( short sHint ) } } - ALERT( at_aiconsole, "Couldn't validate hint type" ); + ALERT( at_aiconsole, "Couldn't validate hint type\n" ); return FALSE; } From 93d1ed029486432af22324582bf3eaf05a6c62cb Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sun, 7 Jul 2019 19:37:24 +0500 Subject: [PATCH 207/211] Add a missing const qualifiers. Remove unneeded casts. --- cl_dll/com_weapons.cpp | 4 ++-- dlls/client.cpp | 4 ++-- dlls/crossbow.cpp | 4 ++-- dlls/crowbar.cpp | 2 +- dlls/egon.cpp | 6 +++--- dlls/gauss.cpp | 10 +++++----- dlls/glock.cpp | 2 +- dlls/hornetgun.cpp | 4 ++-- dlls/mp5.cpp | 2 +- dlls/plats.cpp | 4 ++-- dlls/python.cpp | 2 +- dlls/shotgun.cpp | 4 ++-- dlls/squeakgrenade.cpp | 2 +- dlls/tripmine.cpp | 2 +- dlls/util.h | 4 ++-- engine/cdll_int.h | 14 +++++++------- engine/eiface.h | 12 ++++++------ 17 files changed, 41 insertions(+), 41 deletions(-) diff --git a/cl_dll/com_weapons.cpp b/cl_dll/com_weapons.cpp index 5621149b..05c8bdf9 100644 --- a/cl_dll/com_weapons.cpp +++ b/cl_dll/com_weapons.cpp @@ -116,7 +116,7 @@ void HUD_PlaySound( const char *sound, float volume ) if( !g_runfuncs || !g_finalstate ) return; - gEngfuncs.pfnPlaySoundByNameAtLocation( sound, volume, (float *)&g_finalstate->playerstate.origin ); + gEngfuncs.pfnPlaySoundByNameAtLocation( sound, volume, g_finalstate->playerstate.origin ); } /* @@ -138,7 +138,7 @@ void HUD_PlaybackEvent( int flags, const edict_t *pInvoker, unsigned short event // Weapon prediction events are assumed to occur at the player's origin org = g_finalstate->playerstate.origin; ang = v_angles; - gEngfuncs.pfnPlaybackEvent( flags, pInvoker, eventindex, delay, (float *)&org, (float *)&ang, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2 ); + gEngfuncs.pfnPlaybackEvent( flags, pInvoker, eventindex, delay, org, ang, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2 ); } /* diff --git a/dlls/client.cpp b/dlls/client.cpp index 80b16945..f96302d0 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -1102,8 +1102,8 @@ void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pv } } - *pvs = ENGINE_SET_PVS( (float *)&org ); - *pas = ENGINE_SET_PAS( (float *)&org ); + *pvs = ENGINE_SET_PVS( org ); + *pas = ENGINE_SET_PAS( org ); } #include "entity_state.h" diff --git a/dlls/crossbow.cpp b/dlls/crossbow.cpp index 12d0ff8c..c3f73f4f 100644 --- a/dlls/crossbow.cpp +++ b/dlls/crossbow.cpp @@ -373,7 +373,7 @@ void CCrossbow::FireSniperBolt() flags = 0; #endif - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow2, 0.0, g_vecZero, g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 ); // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); @@ -416,7 +416,7 @@ void CCrossbow::FireBolt() flags = 0; #endif - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usCrossbow, 0.0, g_vecZero, g_vecZero, 0, 0, m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType], 0, 0 ); // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); diff --git a/dlls/crowbar.cpp b/dlls/crowbar.cpp index 4cc48d97..8a0ba9a3 100644 --- a/dlls/crowbar.cpp +++ b/dlls/crowbar.cpp @@ -204,7 +204,7 @@ int CCrowbar::Swing( int fFirst ) if( fFirst ) { PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usCrowbar, - 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, + 0.0, g_vecZero, g_vecZero, 0, 0, 0, 0, 0, 0 ); } diff --git a/dlls/egon.cpp b/dlls/egon.cpp index b83c9086..6f248309 100644 --- a/dlls/egon.cpp +++ b/dlls/egon.cpp @@ -197,7 +197,7 @@ void CEgon::Attack( void ) m_flAmmoUseTime = gpGlobals->time;// start using ammo ASAP. - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, m_fireState, m_fireMode, 1, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, m_fireState, m_fireMode, 1, 0 ); m_shakeTime = 0; @@ -216,7 +216,7 @@ void CEgon::Attack( void ) if( pev->fuser1 <= UTIL_WeaponTimeBase() ) { - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, m_fireState, m_fireMode, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0, g_vecZero, g_vecZero, 0.0, 0.0, m_fireState, m_fireMode, 0, 0 ); pev->fuser1 = 1000; } @@ -504,7 +504,7 @@ void CEgon::EndAttack( void ) if( m_fireState != FIRE_OFF ) //Checking the button just in case!. bMakeNoise = true; - PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, m_pPlayer->edict(), m_usEgonStop, 0, (float *)&m_pPlayer->pev->origin, (float *)&m_pPlayer->pev->angles, 0.0, 0.0, bMakeNoise, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, m_pPlayer->edict(), m_usEgonStop, 0, m_pPlayer->pev->origin, m_pPlayer->pev->angles, 0.0, 0.0, bMakeNoise, 0, 0, 0 ); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0; m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.5; diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index 62af08e1..21377783 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -138,7 +138,7 @@ BOOL CGauss::Deploy() void CGauss::Holster( int skiplocal /* = 0 */ ) { - PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_GLOBAL, m_pPlayer->edict(), m_usGaussFire, 0.01, (float *)&m_pPlayer->pev->origin, (float *)&m_pPlayer->pev->angles, 0.0, 0.0, 0, 0, 0, 1 ); + PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_GLOBAL, m_pPlayer->edict(), m_usGaussFire, 0.01, m_pPlayer->pev->origin, m_pPlayer->pev->angles, 0.0, 0.0, 0, 0, 0, 1 ); m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; @@ -217,7 +217,7 @@ void CGauss::SecondaryAttack() m_pPlayer->m_flStartCharge = gpGlobals->time; m_pPlayer->m_flAmmoStartCharge = UTIL_WeaponTimeBase() + GetFullChargeTime(); - PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usGaussSpin, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 110, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usGaussSpin, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, 110, 0, 0, 0 ); m_iSoundState = SND_CHANGE_PITCH; } @@ -281,7 +281,7 @@ void CGauss::SecondaryAttack() if( m_iSoundState == 0 ) ALERT( at_console, "sound state %d\n", m_iSoundState ); - PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usGaussSpin, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, pitch, 0, ( m_iSoundState == SND_CHANGE_PITCH ) ? 1 : 0, 0 ); + PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usGaussSpin, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, pitch, 0, ( m_iSoundState == SND_CHANGE_PITCH ) ? 1 : 0, 0 ); m_iSoundState = SND_CHANGE_PITCH; // hack for going through level transitions @@ -389,13 +389,13 @@ void CGauss::Fire( Vector vecOrigSrc, Vector vecDir, float flDamage ) g_irunninggausspred = true; #endif // The main firing event is sent unreliably so it won't be delayed. - PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usGaussFire, 0.0, (float *)&m_pPlayer->pev->origin, (float *)&m_pPlayer->pev->angles, flDamage, 0.0, 0, 0, m_fPrimaryFire ? 1 : 0, 0 ); + PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usGaussFire, 0.0, m_pPlayer->pev->origin, m_pPlayer->pev->angles, flDamage, 0.0, 0, 0, m_fPrimaryFire ? 1 : 0, 0 ); // This reliable event is used to stop the spinning sound // It's delayed by a fraction of second to make sure it is delayed by 1 frame on the client // It's sent reliably anyway, which could lead to other delays - PLAYBACK_EVENT_FULL( FEV_NOTHOST | FEV_RELIABLE, m_pPlayer->edict(), m_usGaussFire, 0.01, (float *)&m_pPlayer->pev->origin, (float *)&m_pPlayer->pev->angles, 0.0, 0.0, 0, 0, 0, 1 ); + PLAYBACK_EVENT_FULL( FEV_NOTHOST | FEV_RELIABLE, m_pPlayer->edict(), m_usGaussFire, 0.01, m_pPlayer->pev->origin, m_pPlayer->pev->angles, 0.0, 0.0, 0, 0, 0, 1 ); /*ALERT( at_console, "%f %f %f\n%f %f %f\n", vecSrc.x, vecSrc.y, vecSrc.z, diff --git a/dlls/glock.cpp b/dlls/glock.cpp index 1150d8b9..89dd189e 100644 --- a/dlls/glock.cpp +++ b/dlls/glock.cpp @@ -168,7 +168,7 @@ void CGlock::GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim ) Vector vecDir; vecDir = m_pPlayer->FireBulletsPlayer( 1, vecSrc, vecAiming, Vector( flSpread, flSpread, flSpread ), 8192, BULLET_PLAYER_9MM, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed ); - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), fUseAutoAim ? m_usFireGlock1 : m_usFireGlock2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, ( m_iClip == 0 ) ? 1 : 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), fUseAutoAim ? m_usFireGlock1 : m_usFireGlock2, 0.0, g_vecZero, g_vecZero, vecDir.x, vecDir.y, 0, 0, ( m_iClip == 0 ) ? 1 : 0, 0 ); m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay( flCycleTime ); diff --git a/dlls/hornetgun.cpp b/dlls/hornetgun.cpp index cc63d6db..909ba342 100644 --- a/dlls/hornetgun.cpp +++ b/dlls/hornetgun.cpp @@ -150,7 +150,7 @@ void CHgun::PrimaryAttack() #else flags = 0; #endif - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usHornetFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, FIREMODE_TRACK, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usHornetFire, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, FIREMODE_TRACK, 0, 0, 0 ); // player "shoot" animation m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); @@ -231,7 +231,7 @@ void CHgun::SecondaryAttack( void ) #else flags = 0; #endif - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usHornetFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, FIREMODE_FAST, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usHornetFire, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, FIREMODE_FAST, 0, 0, 0 ); m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME; diff --git a/dlls/mp5.cpp b/dlls/mp5.cpp index 403efa04..426f738a 100644 --- a/dlls/mp5.cpp +++ b/dlls/mp5.cpp @@ -171,7 +171,7 @@ void CMP5::PrimaryAttack() #else flags = 0; #endif - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usMP5, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usMP5, 0.0, g_vecZero, g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) // HEV suit - indicate out of ammo condition diff --git a/dlls/plats.cpp b/dlls/plats.cpp index b3e1c683..5a96a36b 100644 --- a/dlls/plats.cpp +++ b/dlls/plats.cpp @@ -1059,7 +1059,7 @@ void CFuncTrackTrain::StopSound( void ) us_encode = us_sound; PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, - (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 1, 0 ); + g_vecZero, g_vecZero, 0.0, 0.0, us_encode, 0, 1, 0 ); /* STOP_SOUND( ENT( pev ), CHAN_STATIC, STRING( pev->noise ) ); */ @@ -1107,7 +1107,7 @@ void CFuncTrackTrain::UpdateSound( void ) us_encode = us_sound | us_pitch | us_volume; PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, - (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 0, 0 ); + g_vecZero, g_vecZero, 0.0, 0.0, us_encode, 0, 0, 0 ); } } diff --git a/dlls/python.cpp b/dlls/python.cpp index 90606c50..88aa34b5 100644 --- a/dlls/python.cpp +++ b/dlls/python.cpp @@ -200,7 +200,7 @@ void CPython::PrimaryAttack() #else flags = 0; #endif - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usFirePython, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usFirePython, 0.0, g_vecZero, g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) // HEV suit - indicate out of ammo condition diff --git a/dlls/shotgun.cpp b/dlls/shotgun.cpp index a08770b3..03944087 100644 --- a/dlls/shotgun.cpp +++ b/dlls/shotgun.cpp @@ -166,7 +166,7 @@ void CShotgun::PrimaryAttack() vecDir = m_pPlayer->FireBulletsPlayer( 6, vecSrc, vecAiming, VECTOR_CONE_10DEGREES, 2048, BULLET_PLAYER_BUCKSHOT, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed ); } - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usSingleFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usSingleFire, 0.0, g_vecZero, g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) // HEV suit - indicate out of ammo condition @@ -237,7 +237,7 @@ void CShotgun::SecondaryAttack( void ) vecDir = m_pPlayer->FireBulletsPlayer( 12, vecSrc, vecAiming, VECTOR_CONE_10DEGREES, 2048, BULLET_PLAYER_BUCKSHOT, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed ); } - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usDoubleFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usDoubleFire, 0.0, g_vecZero, g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) // HEV suit - indicate out of ammo condition diff --git a/dlls/squeakgrenade.cpp b/dlls/squeakgrenade.cpp index bfe17ed1..a7295599 100644 --- a/dlls/squeakgrenade.cpp +++ b/dlls/squeakgrenade.cpp @@ -508,7 +508,7 @@ void CSqueak::PrimaryAttack() #else flags = 0; #endif - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usSnarkFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usSnarkFire, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); if( tr.fAllSolid == 0 && tr.fStartSolid == 0 && tr.flFraction > 0.25 ) { diff --git a/dlls/tripmine.cpp b/dlls/tripmine.cpp index 94907bcd..6e8fc2fc 100644 --- a/dlls/tripmine.cpp +++ b/dlls/tripmine.cpp @@ -444,7 +444,7 @@ void CTripmine::PrimaryAttack( void ) #else flags = 0; #endif - PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usTripFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); + PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usTripFire, 0.0, g_vecZero, g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); if( tr.flFraction < 1.0 ) { diff --git a/dlls/util.h b/dlls/util.h index 41e86a84..602380ba 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -552,8 +552,8 @@ void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); #define RANDOM_SOUND_ARRAY( array ) (array) [ RANDOM_LONG(0,ARRAYSIZE( (array) )-1) ] -#define PLAYBACK_EVENT( flags, who, index ) PLAYBACK_EVENT_FULL( flags, who, index, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); -#define PLAYBACK_EVENT_DELAY( flags, who, index, delay ) PLAYBACK_EVENT_FULL( flags, who, index, delay, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); +#define PLAYBACK_EVENT( flags, who, index ) PLAYBACK_EVENT_FULL( flags, who, index, 0, g_vecZero, g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); +#define PLAYBACK_EVENT_DELAY( flags, who, index, delay ) PLAYBACK_EVENT_FULL( flags, who, index, delay, g_vecZero, g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); #define GROUP_OP_AND 0 #define GROUP_OP_NAND 1 diff --git a/engine/cdll_int.h b/engine/cdll_int.h index abfc43bd..8ab903b0 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -169,7 +169,7 @@ typedef struct cl_enginefuncs_s int (*GetWindowCenterX)( void ); int (*GetWindowCenterY)( void ); void (*GetViewAngles)( float * ); - void (*SetViewAngles)( float * ); + void (*SetViewAngles)( const float * ); int (*GetMaxClients)( void ); void (*Cvar_SetValue)( const char *cvar, float value ); @@ -195,20 +195,20 @@ typedef struct cl_enginefuncs_s float (*GetClientTime)( void ); void (*V_CalcShake)( void ); - void (*V_ApplyShake)( float *origin, float *angles, float factor ); + void (*V_ApplyShake)( const float *origin, const float *angles, float factor ); - int (*PM_PointContents)( float *point, int *truecontents ); - int (*PM_WaterEntity)( float *p ); - struct pmtrace_s *(*PM_TraceLine)( float *start, float *end, int flags, int usehull, int ignore_pe ); + int (*PM_PointContents)( const float *point, int *truecontents ); + int (*PM_WaterEntity)( const float *p ); + struct pmtrace_s *(*PM_TraceLine)( const float *start, const float *end, int flags, int usehull, int ignore_pe ); struct model_s *(*CL_LoadModel)( const char *modelname, int *index ); int (*CL_CreateVisibleEntity)( int type, struct cl_entity_s *ent ); const struct model_s* (*GetSpritePointer)( HSPRITE hSprite ); - void (*pfnPlaySoundByNameAtLocation)( const char *szSound, float volume, float *origin ); + void (*pfnPlaySoundByNameAtLocation)( const char *szSound, float volume, const float *origin ); unsigned short (*pfnPrecacheEvent)( int type, const char* psz ); - void (*pfnPlaybackEvent)( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); + void (*pfnPlaybackEvent)( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, const float *origin, const float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); void (*pfnWeaponAnim)( int iAnim, int body ); float (*pfnRandomFloat)( float flLow, float flHigh ); int (*pfnRandomLong)( int lLow, int lHigh ); diff --git a/engine/eiface.h b/engine/eiface.h index f6cf2f51..cad60848 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -124,7 +124,7 @@ typedef struct enginefuncs_s int (*pfnWalkMove)( edict_t *ent, float yaw, float dist, int iMode ); void (*pfnSetOrigin)( edict_t *e, const float *rgflOrigin ); void (*pfnEmitSound)( edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch ); - void (*pfnEmitAmbientSound)( edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch ); + void (*pfnEmitAmbientSound)( edict_t *entity, const float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch ); void (*pfnTraceLine)( const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr ); void (*pfnTraceToss)( edict_t* pent, edict_t* pentToIgnore, TraceResult *ptr ); int (*pfnTraceMonsterHull)( edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr ); @@ -219,10 +219,10 @@ typedef struct enginefuncs_s void (*pfnSetPhysicsKeyValue)( const edict_t *pClient, const char *key, const char *value ); const char *(*pfnGetPhysicsInfoString)( const edict_t *pClient ); unsigned short (*pfnPrecacheEvent)( int type, const char*psz ); - void (*pfnPlaybackEvent)( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); - - unsigned char *(*pfnSetFatPVS)( float *org ); - unsigned char *(*pfnSetFatPAS)( float *org ); + void (*pfnPlaybackEvent)( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, const float *origin, const float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); + + unsigned char *(*pfnSetFatPVS)( const float *org ); + unsigned char *(*pfnSetFatPAS)( const float *org ); int (*pfnCheckVisibility )( const edict_t *entity, unsigned char *pset ); @@ -241,7 +241,7 @@ typedef struct enginefuncs_s // Forces the client and server to be running with the same version of the specified file // ( e.g., a player model ). // Calling this has no effect in single player - void (*pfnForceUnmodified)( FORCE_TYPE type, float *mins, float *maxs, const char *filename ); + void (*pfnForceUnmodified)( FORCE_TYPE type, const float *mins, const float *maxs, const char *filename ); void (*pfnGetPlayerStats)( const edict_t *pClient, int *ping, int *packet_loss ); From cf6647e07c452f6522aa8b5a9619a1ac1246f9af Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sun, 7 Jul 2019 19:45:28 +0500 Subject: [PATCH 208/211] Try to fix clang build. --- dlls/extdll.h | 1 + engine/eiface.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/extdll.h b/dlls/extdll.h index d6ea4888..4610db5e 100644 --- a/dlls/extdll.h +++ b/dlls/extdll.h @@ -62,6 +62,7 @@ typedef int BOOL; // Misc C-runtime library headers #include "stdio.h" #include "stdlib.h" +#include "stddef.h" #include "math.h" #if defined(__LP64__) || defined(__LLP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) diff --git a/engine/eiface.h b/engine/eiface.h index cad60848..6a5f86fc 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -355,7 +355,7 @@ typedef enum _fieldtypes FIELD_TYPECOUNT // MUST BE LAST } FIELDTYPE; -#if !defined(offsetof) && !defined(GNUC) +#if !defined(offsetof) && !defined(__GNUC__) #define offsetof(s,m) (size_t)&(((s *)0)->m) #endif From 63b23b96a446efa07109905d01ec24b505d1305b Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sun, 7 Jul 2019 19:49:19 +0500 Subject: [PATCH 209/211] Add a missing con qualifier in HUD_PlaybackEvent function. --- cl_dll/com_weapons.cpp | 2 +- cl_dll/com_weapons.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cl_dll/com_weapons.cpp b/cl_dll/com_weapons.cpp index 05c8bdf9..198c533a 100644 --- a/cl_dll/com_weapons.cpp +++ b/cl_dll/com_weapons.cpp @@ -127,7 +127,7 @@ Directly queue up an event on the client ===================== */ void HUD_PlaybackEvent( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, - float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) + const float *origin, const float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) { vec3_t org; vec3_t ang; diff --git a/cl_dll/com_weapons.h b/cl_dll/com_weapons.h index efe06ad6..89fb3cfe 100644 --- a/cl_dll/com_weapons.h +++ b/cl_dll/com_weapons.h @@ -27,7 +27,7 @@ int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); int HUD_GetWeaponAnim( void ); void HUD_SendWeaponAnim( int iAnim, int body, int force ); void HUD_PlaySound( const char *sound, float volume ); -void HUD_PlaybackEvent( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); +void HUD_PlaybackEvent( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, const float *origin, const float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); void HUD_SetMaxSpeed( const struct edict_s *ed, float speed ); int stub_PrecacheModel( const char* s ); int stub_PrecacheSound( const char* s ); From 40d4e75d4b3bdd2a5a83f5adcbf8b93c41846ec3 Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sun, 7 Jul 2019 20:08:01 +0500 Subject: [PATCH 210/211] Fix warnings. --- cl_dll/cl_dll.h | 2 +- cl_dll/ev_hldm.cpp | 2 ++ dlls/h_battery.cpp | 2 +- dlls/healthkit.cpp | 2 +- dlls/nodes.cpp | 16 +++++++--------- dlls/util.cpp | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cl_dll/cl_dll.h b/cl_dll/cl_dll.h index 6e1c4e69..6ba3db67 100644 --- a/cl_dll/cl_dll.h +++ b/cl_dll/cl_dll.h @@ -38,7 +38,7 @@ typedef int ( *pfnUserMsgHook )( const char *pszName, int iSize, void *pbuf ); #include "../engine/cdll_int.h" #include "../dlls/cdll_dll.h" -#ifndef __MSC_VER +#if !defined(_WIN32) #define _cdecl #endif #include "exportdef.h" diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 08127aa1..f8fefad5 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -1410,7 +1410,9 @@ enum EGON_FIREMODE #define EGON_SOUND_RUN "weapons/egon_run3.wav" #define EGON_SOUND_STARTUP "weapons/egon_windup2.wav" +#if !defined(ARRAYSIZE) #define ARRAYSIZE(p) ( sizeof(p) /sizeof(p[0]) ) +#endif BEAM *pBeam; BEAM *pBeam2; diff --git a/dlls/h_battery.cpp b/dlls/h_battery.cpp index e4c00467..dabbc06c 100644 --- a/dlls/h_battery.cpp +++ b/dlls/h_battery.cpp @@ -118,7 +118,7 @@ void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use } // if the player doesn't have the suit, or there is no juice left, make the deny noise - if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( chargerfix.value ) && ( pActivator->pev->armorvalue == MAX_NORMAL_BATTERY ) ) + if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( ( chargerfix.value ) && ( pActivator->pev->armorvalue == MAX_NORMAL_BATTERY ) ) ) { if( m_flSoundTime <= gpGlobals->time ) { diff --git a/dlls/healthkit.cpp b/dlls/healthkit.cpp index 0f8c521e..e1744479 100644 --- a/dlls/healthkit.cpp +++ b/dlls/healthkit.cpp @@ -188,7 +188,7 @@ void CWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE u } // if the player doesn't have the suit, or there is no juice left, make the deny noise - if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( chargerfix.value ) && ( pActivator->pev->health >= pActivator->pev->max_health ) ) + if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) || ( ( chargerfix.value ) && ( pActivator->pev->health >= pActivator->pev->max_health ) ) ) { if( m_flSoundTime <= gpGlobals->time ) { diff --git a/dlls/nodes.cpp b/dlls/nodes.cpp index e81f3252..6babe01d 100644 --- a/dlls/nodes.cpp +++ b/dlls/nodes.cpp @@ -45,9 +45,7 @@ LINK_ENTITY_TO_CLASS( info_node_air, CNodeEnt ) #if !defined _WIN32 #include #include -#define CreateDirectory(p, n) mkdir(p, 0777) -#else -#define CreateDirectory(p, n) CreateDirectoryA(p, n) +#define CreateDirectoryA(p, n) mkdir(p, 0777) #endif //========================================================= @@ -1702,9 +1700,9 @@ void CTestHull::BuildNodeGraph( void ) // make sure directories have been made GET_GAME_DIR( szNrpFilename ); strcat( szNrpFilename, "/maps" ); - CreateDirectory( szNrpFilename, NULL ); + CreateDirectoryA( szNrpFilename, NULL ); strcat( szNrpFilename, "/graphs" ); - CreateDirectory( szNrpFilename, NULL ); + CreateDirectoryA( szNrpFilename, NULL ); strcat( szNrpFilename, "/" ); strcat( szNrpFilename, STRING( gpGlobals->mapname ) ); @@ -2376,9 +2374,9 @@ int CGraph::FLoadGraph( const char *szMapName ) char szDirName[MAX_PATH]; GET_GAME_DIR( szDirName ); strcat( szDirName, "/maps" ); - CreateDirectory( szDirName, NULL ); + CreateDirectoryA( szDirName, NULL ); strcat( szDirName, "/graphs" ); - CreateDirectory( szDirName, NULL ); + CreateDirectoryA( szDirName, NULL ); strcpy( szFilename, "maps/graphs/" ); strcat( szFilename, szMapName ); @@ -2585,9 +2583,9 @@ int CGraph::FSaveGraph( const char *szMapName ) // make sure directories have been made GET_GAME_DIR( szFilename ); strcat( szFilename, "/maps" ); - CreateDirectory( szFilename, NULL ); + CreateDirectoryA( szFilename, NULL ); strcat( szFilename, "/graphs" ); - CreateDirectory( szFilename, NULL ); + CreateDirectoryA( szFilename, NULL ); strcat( szFilename, "/" ); strcat( szFilename, szMapName ); diff --git a/dlls/util.cpp b/dlls/util.cpp index c7feab31..a5160876 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -1733,8 +1733,8 @@ void CSaveRestoreBuffer::BufferRewind( int size ) extern "C" { unsigned _rotr( unsigned val, int shift ) { - register unsigned lobit; /* non-zero means lo bit set */ - register unsigned num = val; /* number to rotate */ + unsigned lobit; /* non-zero means lo bit set */ + unsigned num = val; /* number to rotate */ shift &= 0x1f; /* modulo 32 -- this will also make negative shifts work */ From f6135287e6f701ddf20e09c5066777d557f6ad20 Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sun, 7 Jul 2019 20:30:20 +0500 Subject: [PATCH 211/211] Remove some strange code. --- dlls/sound.cpp | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/dlls/sound.cpp b/dlls/sound.cpp index 30c44326..6637fe53 100644 --- a/dlls/sound.cpp +++ b/dlls/sound.cpp @@ -1037,9 +1037,8 @@ void USENTENCEG_InitLRU( unsigned char *plru, int count ) int USENTENCEG_PickSequential( int isentenceg, char *szfound, int ipick, int freset ) { - char *szgroupname; + const char *szgroupname; unsigned char count; - char sznum[8]; if( !fSentencesInit ) return -1; @@ -1056,10 +1055,7 @@ int USENTENCEG_PickSequential( int isentenceg, char *szfound, int ipick, int fre if( ipick >= count ) ipick = count - 1; - strcpy( szfound, "!" ); - strcat( szfound, szgroupname ); - sprintf( sznum, "%d", ipick ); - strcat( szfound, sznum ); + sprintf( szfound, "!%s%d", szgroupname, ipick ); if( ipick >= count ) { @@ -1083,11 +1079,10 @@ int USENTENCEG_PickSequential( int isentenceg, char *szfound, int ipick, int fre int USENTENCEG_Pick( int isentenceg, char *szfound ) { - char *szgroupname; + const char *szgroupname; unsigned char *plru; unsigned char i; unsigned char count; - char sznum[8]; unsigned char ipick; int ffound = FALSE; @@ -1116,10 +1111,8 @@ int USENTENCEG_Pick( int isentenceg, char *szfound ) USENTENCEG_InitLRU( plru, count ); else { - strcpy( szfound, "!" ); - strcat( szfound, szgroupname ); - sprintf( sznum, "%d", ipick ); - strcat( szfound, sznum ); + sprintf( szfound, "!%s%d", szgroupname, ipick ); + return ipick; } } @@ -1227,7 +1220,6 @@ int SENTENCEG_PlaySequentialSz( edict_t *entity, const char *szgroupname, float void SENTENCEG_Stop( edict_t *entity, int isentenceg, int ipick ) { char buffer[64]; - char sznum[8]; if( !fSentencesInit ) return; @@ -1235,10 +1227,7 @@ void SENTENCEG_Stop( edict_t *entity, int isentenceg, int ipick ) if( isentenceg < 0 || ipick < 0 ) return; - strcpy( buffer, "!" ); - strcat( buffer, rgsentenceg[isentenceg].szgroupname ); - sprintf( sznum, "%d", ipick ); - strcat( buffer, sznum ); + sprintf( buffer, "!%s%d", rgsentenceg[isentenceg].szgroupname, ipick ); STOP_SOUND( entity, CHAN_VOICE, buffer ); } @@ -1369,9 +1358,8 @@ void SENTENCEG_Init() int SENTENCEG_Lookup( const char *sample, char *sentencenum ) { - char sznum[8]; - int i; + // this is a sentence name; lookup sentence number // and give to engine as string. for( i = 0; i < gcallsentences; i++ ) @@ -1379,9 +1367,7 @@ int SENTENCEG_Lookup( const char *sample, char *sentencenum ) { if( sentencenum ) { - strcpy( sentencenum, "!" ); - sprintf( sznum, "%d", i ); - strcat( sentencenum, sznum ); + sprintf(sentencenum, "!%d", i); } return i; }