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_count, NumberType_Int32);
int iValidAreaCount = 0;
//Check that this map has any nav areas
if ( iAreaCount > 0 )
{
//Get a random area 10 times
for (int i = 0; i <= 10; i++)
{
//Get random area
Address RandomArea = view_as<Address>(LoadFromAddress(TheNavAreas + view_as<Address>(4 * GetRandomInt(0, iAreaCount - 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_nwCorner, m_seCorner, vecPos);
ScaleVector(vecPos, 0.5);
//Check if any player can see this place
if(UTIL_IsVisibleToTeam(vecPos, 2))
continue;
if(UTIL_IsVisibleToTeam(vecPos, 3))
continue;
CreateEntity(vecPos);
iValidAreaCount++;
}
}
}
stock bool UTIL_IsVisibleToTeam(float vecPos[3], int team)
{
for (int i = 1; i <= MaxClients; i++)
{
if(!IsClientInGame(i))
continue;
if(!IsPlayerAlive(i))
continue;
if(GetClientTeam(i) != team)
continue;
if(!IsLineOfFireClear(vecPos, GetEyePosition(i)))
continue;
return true;
}
return false;
}
stock bool IsLineOfFireClear(float from[3], float to[3])
{
Handle trace = TR_TraceRayFilterEx(from, to, CONTENTS_SOLID|CONTENTS_MOVEABLE|0x40|CONTENTS_MONSTER, RayType_EndPoint, FilterPlayers);
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
__________________