summaryrefslogtreecommitdiff
path: root/cheat/internal_rewrite/visual_world.cpp
diff options
context:
space:
mode:
authorboris <wzn@moneybot.cc>2018-11-28 16:00:02 +1300
committerboris <wzn@moneybot.cc>2018-11-28 16:00:02 +1300
commit3d412a4b30a9f7c7f51ea6562e694315948bd3da (patch)
tree26d67dfd1f3e5fd12903ad13e85d0cb8bcf8f21c /cheat/internal_rewrite/visual_world.cpp
parente4729e4393d90271a3814c7a79950a660c48325a (diff)
cleaned up
in short, the cheat and loader are now separate solutions. unused stuff was moved into the legacy solution in case anyone wants to compile it or whatever. i can change this back if you want to. also, i configured the loader to compile in x64, and have separate build types for linux and win64
Diffstat (limited to 'cheat/internal_rewrite/visual_world.cpp')
-rw-r--r--cheat/internal_rewrite/visual_world.cpp415
1 files changed, 415 insertions, 0 deletions
diff --git a/cheat/internal_rewrite/visual_world.cpp b/cheat/internal_rewrite/visual_world.cpp
new file mode 100644
index 0000000..ea3d31d
--- /dev/null
+++ b/cheat/internal_rewrite/visual_world.cpp
@@ -0,0 +1,415 @@
+#include <unordered_map>
+#include <cmath>
+#include "context.hpp"
+#include "visual.hpp"
+#include "interface.hpp"
+#include "renderer.hpp"
+#include "base_cheat.hpp"
+namespace features
+{
+ void fix_static_props( ) {
+ static auto cvar = g_csgo.m_cvar( )->FindVar( xors( "r_drawspecificstaticprop" ) );
+ static bool fixed{ };
+ if( !fixed ) {
+ cvar->m_flags |= 0;
+ cvar->set_value( 1 );
+
+ fixed = true;
+ }
+ }
+
+ void c_visuals::store_firegrenades( int index, vec3_t pos ) {
+ firegrenade_t new_grenade;
+
+ auto ent = g_csgo.m_entlist( )->GetClientEntity< >( index );
+ if( !ent || !ent->is_player( ) )
+ return;
+
+
+ new_grenade.m_time = g_csgo.m_globals->m_curtime;
+ new_grenade.m_ent = index;
+ new_grenade.m_pos = pos;
+
+ m_firegrenades.emplace_back( new_grenade );
+ }
+
+ void c_visuals::draw_world( ) {
+ if( !g_settings.visuals.active )
+ return;
+
+ static const auto m_bShouldGlow = g_netvars.get_netvar( fnv( "DT_DynamicProp" ), fnv( "m_bShouldGlow" ) );
+ static auto c4_time = g_csgo.m_cvar( )->FindVar( xors( "mp_c4timer" ) );
+
+ draw_firegrenade( );
+
+ for( int i{ 64 }; i < g_csgo.m_entlist( )->GetHighestEntityIndex( ); ++i ) {
+ auto ent = g_csgo.m_entlist( )->GetClientEntity< IClientEntity >( i );
+ if( !ent ) continue;
+
+ auto client_class = ent->GetClientClass( );
+ if( !client_class ) continue;
+
+ int class_id = client_class->m_class_id;
+
+ if( g_settings.visuals.bomb_info && class_id == CPlantedC4 && ( strstr( client_class->m_name, xors( "Planted" ) ) ) ) {
+ //yea i know this is yuck i just want to get it out there for now, ill revisit it sometime in the week
+ //not bad at all tbh
+ int screen_w, screen_h;
+ g_csgo.m_engine( )->GetScreenSize( screen_w, screen_h );
+
+ auto pos = ent->GetRenderOrigin( );
+ auto w2s = util::screen_transform( pos );
+ auto bomb = ent->as< c_base_weapon >( );
+ auto to_target = pos - g_ctx.m_local->ce( )->GetRenderOrigin( );
+
+ float bomb_time = bomb->m_flC4Blow( ) - g_csgo.m_globals->m_curtime;
+ float bomb_percentage = bomb_time / c4_time->get_float( );
+ float time = ( bomb_time < 0 || bomb->m_bBombDefused( ) ) ? 0.f : bomb_time;
+
+ if( time <= 0.f )
+ return;
+
+ bool out_of_pov = w2s.x > screen_w || w2s.x < 0.f || w2s.y > screen_h || w2s.y < 0.f;
+ if( out_of_pov ) {
+ static auto safezoney = g_csgo.m_cvar( )->FindVar( xors( "safezoney" ) );
+ static auto hud_scaling = g_csgo.m_cvar( )->FindVar( xors( "hud_scaling" ) );
+
+ w2s.x = screen_w / 2;
+ w2s.y = ( 45 * hud_scaling->get_float( ) ) + ( screen_h - screen_h * safezoney->get_float( ) + 1 ) * 0.5f;
+ }
+
+ float bomb_damage = 500 * exp( -((to_target.length( ) * to_target.length( ) ) / ( ( ( 1750 * 0.33333334 ) * 2.f ) * ( 1750 * 0.33333334 ) ) ) );
+ float damage = bomb_damage;
+
+ if( g_ctx.m_local->m_ArmorValue( ) > 0 ) {
+ damage *= 0.5f;
+ float armor = ( bomb_damage - damage ) * 0.5f;
+ if( armor > g_ctx.m_local->m_ArmorValue( ) )
+ damage = bomb_damage - ( g_ctx.m_local->m_ArmorValue( ) * ( 1.f / 0.5f ) );
+ }
+
+ int health_remaining = g_ctx.m_local->m_iHealth( ) - round(damage);
+
+ float damage_percentage = std::clamp( round( damage ) / g_ctx.m_local->m_iHealth( ), 0.f, 1.0f );
+
+ clr_t bomb_col = clr_t::blend( esp_red( ), esp_green( ), bomb_percentage );
+ clr_t damage_col = clr_t::blend( esp_green( ), esp_red( ), damage_percentage );
+
+ char health_str[ 100 ];
+
+ strenc::w_sprintf_s( health_str, 100, xors( "health: %d" ), health_remaining );
+
+ if( health_remaining <= 0 ) {
+ strenc::w_sprintf_s( health_str, 100, xors( "dead" ) );
+ damage_percentage = 100.f;
+ }
+
+ draw_string( w2s.x, w2s.y + 20, ALIGN_CENTER, false, damage_col, health_str );
+
+ auto draw_timer = [ & ]( const char* text, float progress, bool red = false ) {
+ clr_t col = red ? esp_red( ) : clr_t::blend( esp_green( ), esp_red( ), progress );
+
+ const float full = 78.f;
+ float fill = full * progress;
+
+ draw_filled_rect( w2s.x - 40, w2s.y, 80, 18, clr_t( 0, 0, 0, 170 ) );
+ draw_filled_rect( w2s.x - 39, w2s.y + 1, fill, 16, col );
+
+ draw_string( w2s.x, w2s.y + 3, ALIGN_CENTER, false, clr_t( 255, 255, 255 ), text );
+ };
+
+ if( bomb->m_hBombDefuser( ) != ULONG_MAX ) {
+ auto defuser = g_csgo.m_entlist( )->GetClientEntity( bomb->m_hBombDefuser( ) & 0xfff );
+
+ float defuse_time = std::clamp( bomb->m_flDefuseCountDown( ) - g_csgo.m_globals->m_curtime, 0.f, 10.f );
+ float defuse_percentage = defuser->m_bHasDefuser( ) ? defuse_time / 5.f : defuse_time / 10.f;
+
+ char defuse_str[ 32 ];
+ strenc::w_sprintf_s( defuse_str, 32, xors( "defuse: %.1f" ), defuse_time );
+
+ draw_timer( defuse_str, 1.f - defuse_percentage, defuse_time > bomb_time );
+ }
+ else {
+ char bomb_str[ 32 ];
+ strenc::w_sprintf_s( bomb_str, 32, xors( "bomb: %.1f" ), bomb_time );
+
+ draw_timer( bomb_str, 1.f - bomb_percentage );
+ }
+ }
+
+ if( class_id != CBaseWeaponWorldModel && ( strstr( client_class->m_name, xors( "Weapon" ) )
+ || class_id == CDEagle || class_id == CAK47 ) ) {
+ auto owner = ( int )ent->as< c_base_weapon >( )->m_hOwner( ) & 0xfff;
+ if( owner <= 0 || owner > 64 ) {
+ auto origin = ent->GetRenderOrigin( );
+ if( origin ) {
+ bool draw = g_settings.visuals.weapon_esp( ) == 1;
+ bool glow = g_settings.visuals.weapon_esp( ) == 2;
+
+ if( draw || g_settings.visuals.weapon_esp == 3 ) {
+ if( !glow && !g_settings.misc.hide_from_obs ) {
+ *( bool* )( uintptr_t( ent ) + m_bShouldGlow ) = false;
+ }
+
+ auto w2s = util::screen_transform( origin );
+ auto def_index = ent->as< c_base_weapon >( )->m_iItemDefinitionIndex( );
+ auto name = util::definition_index_to_name( def_index );
+
+ auto dist = g_ctx.m_local->m_vecOrigin( ).dist_to( origin );
+
+ clr_t col = g_settings.visuals.weapon_esp_clr;
+ if( dist > 250.f ) {
+ col.a( ) *= std::clamp( ( 750.f - ( dist - 250.f ) ) / 750.f, 0.f, 1.f );
+ };
+
+ draw_string( w2s.x, w2s.y, ALIGN_CENTER, false,
+ col, name );
+ }
+ if( ( glow || g_settings.visuals.weapon_esp == 3 ) && !g_settings.misc.hide_from_obs ) {
+ *( bool* )( uintptr_t( ent ) + m_bShouldGlow ) = true;
+ }
+ }
+ }
+ }
+ else {
+ if( g_settings.visuals.grenade_esp && strstr( client_class->m_name, xors( "Projectile" ) ) ) {
+ auto model = ent->GetModel( );
+ if( !model ) continue;
+
+ auto hdr = g_csgo.m_model_info( )->GetStudiomodel( model );
+ if( !strstr( hdr->name, xors( "thrown" ) ) && !strstr( hdr->name, xors( "dropped" ) ) )
+ continue;
+
+ bool fade = false;
+
+ std::string name = xors( "nade" );
+ if( strstr( hdr->name, xors( "flash" ) ) ) {
+ name = xors( "flash" );
+ fade = true;
+ }
+ else if( strstr( hdr->name, xors( "smoke" ) ) ) {
+ name = xors( "smoke" );
+ fade = true;
+ }
+ else if( strstr( hdr->name, xors( "decoy" ) ) ) {
+ name = xors( "decoy" );
+ fade = true;
+ }
+ else if( strstr( hdr->name, xors( "incendiary" ) ) || strstr( hdr->name, xors( "molotov" ) ) ) {
+ name = xors( "molotov" );
+ }
+
+ if( ( g_settings.visuals.grenade_esp == 2 || g_settings.visuals.grenade_esp == 3 ) && !g_settings.misc.hide_from_obs ) {
+ *( bool* )( uintptr_t( ent ) + m_bShouldGlow ) = true;
+ }
+
+ if( g_settings.visuals.grenade_esp == 1 || g_settings.visuals.grenade_esp == 3 ) {
+ auto pos = ent->GetRenderOrigin( );
+ auto w2s = util::screen_transform( pos );
+ auto cutie = g_csgo.m_entlist( )->GetClientEntityFromHandle( ent->as< c_base_weapon >( )->m_hOwnerEntity( ) );
+
+ auto dist = g_ctx.m_local->m_vecOrigin( ).dist_to( pos );
+
+ clr_t col = g_settings.visuals.grenade_esp_clr( );
+ if( dist > 250.f && fade ) {
+ col.a( ) *= std::max( ( 1000.f - ( dist - 250.f ) ) / 1000.f, 0.f );
+ }
+
+ draw_string( w2s.x, w2s.y, ALIGN_CENTER, false,
+ col, name.c_str( ) );
+
+ char name[ 32 ];
+ cutie->get_name_safe( name );
+
+ if( g_settings.visuals.grenade_owner( ) )
+ draw_string( w2s.x, w2s.y + 10, ALIGN_CENTER, false, col, name );
+ }
+ }
+ }
+ }
+ }
+
+ void c_visuals::draw_firegrenade( ) {
+ static auto life_span = g_csgo.m_cvar( )->FindVar( xors( "inferno_flame_lifetime" ) );
+ float time = g_csgo.m_globals->m_curtime;
+
+ if( m_firegrenades.empty( ) )
+ return;
+
+ for( size_t i{ }; i < m_firegrenades.size( ) && !m_firegrenades.empty( ); ++i ) {
+ auto& tr = m_firegrenades[ i ];
+
+ float delta = g_csgo.m_globals->m_curtime - tr.m_time;
+ if( std::abs( delta ) > life_span->get_float( ) ) m_firegrenades.erase( m_firegrenades.begin( ) + i );
+ }
+
+ if( !m_firegrenades.empty( ) ) {
+ for( auto& it : m_firegrenades ) {
+ auto ent = g_csgo.m_entlist( )->GetClientEntity( it.m_ent );
+ if( !ent || !ent->is_player( ) )
+ continue;
+
+ clr_t col = g_settings.visuals.grenade_esp_clr;
+
+ vec3_t text_pos = it.m_pos;
+ text_pos.z += 5.f;
+
+ auto w2s = util::screen_transform( text_pos );
+
+ float delta = g_csgo.m_globals->m_curtime - it.m_time;
+
+ if( g_ctx.m_local->is_valid( ) && ( ent->m_iTeamNum( ) != g_ctx.m_local->m_iTeamNum( ) || ent == g_ctx.m_local ) ) {
+ vec3_t last_pos;
+
+ const float fill = ( life_span->get_float( ) - delta ) / ( life_span->get_float( ) ) * 180.f;
+
+ for( float rot = -fill; rot <= fill; rot += 3.f ) {
+ auto rotation = rot + delta * 90.f;
+
+ while( rotation > 360.f )
+ rotation -= 360.f;
+
+ vec3_t rotated_pos = it.m_pos;
+
+ rotated_pos.z -= 5.f;
+
+ const auto radius = 50.f;
+ rotated_pos.x += cos( DEG2RAD( rotation ) ) * radius;
+ rotated_pos.y += sin( DEG2RAD( rotation ) ) * radius;
+
+ if( rot != -fill ) {
+ auto w2s_new = util::screen_transform( rotated_pos );
+ auto w2s_old = util::screen_transform( last_pos );
+ auto alpha = 1.f - ( std::abs( rot ) / fill );
+
+ float threshold = life_span->get_float( ) * 0.2f;
+
+ if( life_span->get_float( ) - delta < threshold ) {
+ float diff = ( life_span->get_float( ) - delta ) / ( life_span->get_float( ) ) * 5.f;
+
+ alpha *= diff;
+ }
+
+ clr_t col = g_settings.visuals.grenade_esp_clr;
+
+ col.a( ) *= alpha;
+
+ draw_line( w2s_old, w2s_new, col );
+ }
+
+ last_pos = rotated_pos;
+ }
+ }
+
+ draw_string( w2s.x, w2s.y, ALIGN_CENTER, false, col, xors( "molotov" ) );
+ if( g_settings.visuals.grenade_owner )
+ draw_string( w2s.x, w2s.y + 10, ALIGN_CENTER, false, col, ent->get_info( ).name );
+ }
+ }
+ }
+
+ void c_visuals::world_modulate( ) {
+ static std::unordered_map< MaterialHandle_t, fclr_t > world_materials;
+ static std::unordered_map< MaterialHandle_t, fclr_t > world_materials2;
+ static c_base_player* local_player = nullptr;
+ static auto night_mode = false;
+ static bool modulated = false;
+ static bool alpha = false;
+
+ if( !g_settings.visuals.world_modulate || !g_csgo.m_engine( )->IsInGame( ) || g_settings.misc.hide_from_obs ) {
+ modulated = false;
+ if( !world_materials2.empty( ) ) {
+ for( auto& it : world_materials2 ) {
+ auto mat = g_csgo.m_mat_system( )->GetMaterial( it.first );
+ if( !mat ) continue;
+
+ auto original_col = it.second;
+ mat->ColorModulate( original_col.r( ), original_col.g( ), original_col.b( ) );
+ mat->AlphaModulate( original_col.a( ) );
+ }
+
+ world_materials.clear( );
+ world_materials2.clear( );
+ }
+
+ return;
+ }
+
+ if( g_ctx.m_stage == FRAME_NET_UPDATE_POSTDATAUPDATE_END ) {
+ fix_static_props( );
+
+ if( local_player == g_ctx.m_local &&
+ night_mode == g_settings.visuals.night_mode( ) &&
+ alpha == g_settings.visuals.transparent_props( ) &&
+ modulated == g_settings.visuals.world_modulate( ) )
+ return;
+
+
+ for( auto i = g_csgo.m_mat_system( )->FirstMaterial( );
+ i != g_csgo.m_mat_system( )->InvalidMaterial( );
+ i = g_csgo.m_mat_system( )->NextMaterial( i ) ) {
+
+ auto mat = g_csgo.m_mat_system( )->GetMaterial( i );
+ if( !mat ) continue;
+
+ const char* group = mat->GetTextureGroupName( );
+ bool is_world = strstr( group, xors( "World" ) );
+ bool is_sky = strstr( group, xors( "Sky" ) );
+ bool is_prop = strstr( group, xors( "StaticProp" ) );
+
+ if( is_world || is_sky || is_prop ) {
+ const char* name = mat->GetName( );
+ if( world_materials.find( i ) == world_materials.end( ) ) {
+ fclr_t clr;
+
+ mat->GetColorModulate( &clr.r( ), &clr.g( ), &clr.b( ) );
+ clr.a( ) = mat->GetAlphaModulation( );
+
+ world_materials.emplace( i, clr );
+ world_materials2.emplace( i, clr );
+ }
+
+ fclr_t new_color;
+
+ new_color = world_materials2.find( i )->second;
+ bool apply = g_settings.visuals.night_mode && g_settings.visuals.world_modulate;
+
+ if( is_world ) {
+ if( apply ) {
+ new_color.r( ) *= 0.15f;
+ new_color.g( ) *= 0.15f;
+ new_color.b( ) *= 0.15f;
+ }
+ }
+ else if( is_prop ) {
+ if( apply ) {
+ new_color.r( ) *= 0.3f;
+ new_color.g( ) *= 0.3f;
+ new_color.b( ) *= 0.3f;
+ }
+ if( g_settings.visuals.world_modulate && g_settings.visuals.transparent_props ) {
+ new_color.a( ) *= 0.6f;
+ }
+ }
+ else if( is_sky ) {
+ if( apply ) {
+ new_color = fclr_t( 0.f, 0.f, 0.f );
+ }
+ }
+
+ if( !( world_materials.at( i ) == new_color ) ) {
+ mat->ColorModulate( new_color.r( ), new_color.g( ), new_color.b( ) );
+ mat->AlphaModulate( new_color.a( ) );
+
+ world_materials.at( i ) = new_color;
+ }
+ }
+ }
+
+ modulated = g_settings.visuals.world_modulate;
+ night_mode = g_settings.visuals.night_mode;
+ alpha = g_settings.visuals.transparent_props;
+ local_player = g_ctx.m_local;
+ }
+ }
+} \ No newline at end of file