View Single Post
Author Message
Pelipoika
Veteran Member
Join Date: May 2012
Location: Inside
Old 02-12-2018 , 12:17   [CSGO] Doing stuff with TheNavAreas and navarea_count
Reply With Quote #1

Gamedata

Code:
"Games"
{
	"csgo"
	{
		"Addresses"
		{
			"navarea_count"
			{
				"windows"
				{
					"signature" "nav_update_lighting" 
					"read" "92"
				}
				"linux"
				{
					"signature" "nav_update_lighting" 
					"read" "18"
				}
			}
		}
		"Signatures"
		{
			"nav_update_lighting"	//nav_update_lighting(CCommand const&) | STR "Computed lighting for %d/%d areas\n"
			{
				"windows"	"\x55\x8B\xEC\x8B\x45\x08\x57\x33\xFF"
				"linux"		"\x55\x89\xE5\x56\x53\x83\xEC\x10\x8B\x45\x08\x83\x38\x02"
			}
		}
	}
}
Plugin
PHP Code:
Address TheNavAreas;
Address navarea_count;

//You want to do this in OnMapStart or else after a map change you will have a bad address
public void OnMapStart()
{
    
Handle hConf LoadGameConfigFile("yourgamedata.txt");
    
    
navarea_count GameConfGetAddress(hConf"navarea_count");
    
PrintToServer("Found \"navarea_count\" @ 0x%X"navarea_count);
    
    
//TheNavAreas is nicely above navarea_count
    
TheNavAreas view_as<Address>(LoadFromAddress(navarea_count view_as<Address>(0x4), NumberType_Int32));
    
PrintToServer("Found \"TheNavAreas\" @ 0x%X"TheNavAreas);
    
    
delete hConf;

Useful things you may do with this
PHP Code:
//Get areas that are bigger than 50 units wide and maybe spawn stuff on them
//Say you were making a hunger games gamemode or a true random spawns deathmatch mode, 
//you could use this to always have a truly random spawn for your player or hunger games loot.
//Yes this is the exact code CS:GO uses to keep the map populated with chickens

void DoStuff()
{
    
int iAreaCount LoadFromAddress(navarea_countNumberType_Int32);

    
int iValidAreaCount 0;
    
    
//Check that this map has any nav areas
    
if ( iAreaCount )
    {
        
//Get a random area 10 times
        
for (int i 0<= 10i++)
        {
            
//Get random area
            
Address RandomArea view_as<Address>(LoadFromAddress(TheNavAreas view_as<Address>(GetRandomInt(0iAreaCount 1)), NumberType_Int32));
            
            
float m_nwCorner[3];
            
m_nwCorner[0] = view_as<float>(LoadFromAddress(RandomArea view_as<Address>(4), NumberType_Int32));
            
m_nwCorner[1] = view_as<float>(LoadFromAddress(RandomArea view_as<Address>(8), NumberType_Int32));
            
m_nwCorner[2] = view_as<float>(LoadFromAddress(RandomArea view_as<Address>(12), NumberType_Int32));
            
            
float m_seCorner[3];
            
m_seCorner[0] = view_as<float>(LoadFromAddress(RandomArea view_as<Address>(16), NumberType_Int32));
            
m_seCorner[1] = view_as<float>(LoadFromAddress(RandomArea view_as<Address>(20), NumberType_Int32));
            
m_seCorner[2] = view_as<float>(LoadFromAddress(RandomArea view_as<Address>(24), NumberType_Int32));
            
            
//Check that the area is bigger than 50 units wide on both sides.
            
if((m_seCorner[0] - m_nwCorner[0]) <= 50.0)
                continue;
            
            if((
m_seCorner[1] - m_nwCorner[1]) <= 50.0)
                continue;
            
            
//Calculate area center position.
            
float vecPos[3];
            
AddVectors(m_nwCornerm_seCornervecPos);
            
ScaleVector(vecPos0.5);
            
            
//Check if any player can see this place
            
if(UTIL_IsVisibleToTeam(vecPos2))
                continue;
            
            if(
UTIL_IsVisibleToTeam(vecPos3))
                continue;
            
            
CreateEntity(vecPos);
            
iValidAreaCount++;
        }
    }
}

stock bool UTIL_IsVisibleToTeam(float vecPos[3], int team)
{
    for (
int i 1<= MaxClientsi++)
    {
        if(!
IsClientInGame(i))
            continue;
            
        if(!
IsPlayerAlive(i))
            continue;
            
        if(
GetClientTeam(i) != team)
            continue;
        
        if(!
IsLineOfFireClear(vecPosGetEyePosition(i)))
            continue;
            
        return 
true;
    }
    
    return 
false;
}

stock bool IsLineOfFireClear(float from[3], float to[3])
{
    
Handle trace TR_TraceRayFilterEx(fromtoCONTENTS_SOLID|CONTENTS_MOVEABLE|0x40|CONTENTS_MONSTERRayType_EndPointFilterPlayers);
    
    
float flFraction TR_GetFraction(trace);
    
    
delete trace;
    
    if (
flFraction >= 1.0/* && !trace.allsolid*/
    {
        return !(
flFraction == 0.0);    //allsolid
    
}
    
    return 
false;

WINDOWS Gamedata has been tested and confirmed working
LINUX Gamedata also works according to Rachnus
__________________

Last edited by Pelipoika; 07-31-2018 at 11:34.
Pelipoika is offline