Пользователь
-
Автор темы
- #1
Ok, there is nothing hard here, because network strings are already here.
1. Only add SetModelIndex into entity.h
C++:
__forceinline void SetModelIndex(int index)
{
return util::get_method< void(__thiscall*)(void*, int)>(this, 75)(this, index);
}
.h
Код:
#pragma once
class agent_changer {
public:
void SetupAgents();
};
extern agent_changer g_agents;
.cpp
C++:
#include "includes.h"
/*
░██████╗██╗░░░██╗██████╗░██████╗░███████╗███╗░░░███╗░█████╗░░█████╗░██╗░░░██╗ ░█████╗░░██████╗██╗░██████╗░░█████╗░
██╔════╝██║░░░██║██╔══██╗██╔══██╗██╔════╝████╗░████║██╔══██╗██╔══██╗╚██╗░██╔╝ ██╔══██╗██╔════╝╚═╝██╔════╝░██╔══██╗
╚█████╗░██║░░░██║██████╔╝██████╔╝█████╗░░██╔████╔██║███████║██║░░╚═╝░╚████╔╝░ ██║░░╚═╝╚█████╗░░░░██║░░██╗░██║░░██║
░╚═══██╗██║░░░██║██╔═══╝░██╔══██╗██╔══╝░░██║╚██╔╝██║██╔══██║██║░░██╗░░╚██╔╝░░ ██║░░██╗░╚═══██╗░░░██║░░╚██╗██║░░██║
██████╔╝╚██████╔╝██║░░░░░██║░░██║███████╗██║░╚═╝░██║██║░░██║╚█████╔╝░░░██║░░░ ╚█████╔╝██████╔╝██╗╚██████╔╝╚█████╔╝
╚═════╝░░╚═════╝░╚═╝░░░░░╚═╝░░╚═╝╚══════╝╚═╝░░░░░╚═╝╚═╝░░╚═╝░╚════╝░░░░╚═╝░░░ ░╚════╝░╚═════╝░╚═╝░╚═════╝░░╚════╝░
*/
agent_changer g_agents{ };
// Bind only once
bool ForceOnce = false;
bool LoadModel = false;
// This is how custom player models working.
// U need to precache them first and use only after that.
bool LockNLoad(const char* MdlName)
{
// hooking INetworkStringTable
INetworkStringTable* m_supremacy_model = g_csgo.m_networkstringtable->FindTable("modelprecache");
if (m_supremacy_model)
{
g_csgo.m_model_info->FindOrLoadModel(MdlName);
int modelindex = m_supremacy_model->AddString(false, MdlName);
if (modelindex == NULL) // if not exists, skip
return false;
}
return true;
}
// setup models
void agent_changer::SetupAgents()
{
// call this once
if (!g_menu.main.config.enable_agent.get())
{
// Strip to default?
g_cl.m_local->SetModelIndex(g_csgo.m_model_info->GetModelIndex("models/player/custom_player/legacy/ctm_sas_variantf.mdl"));
ForceOnce = true;
LoadModel = false;
return;
}
// lock
else
ForceOnce = false;
if (ForceOnce == false)
{
// For example let's precache Counter-Strike Online 2 player operators
// Download them first OFC
if (LoadModel == false)
{
// Don't change the models path, it's defined in .mdl source code
LockNLoad("models/player/custom_player/kuristaja/cso2/sas/sas.mdl");
LoadModel = true; // we done here, no need to spam this
}
static int iModel = g_menu.main.config.agent_change.get();
if (g_menu.main.config.agent_change.get() == 1)
iModel = g_csgo.m_model_info->GetModelIndex("models/player/custom_player/kuristaja/cso2/sas/sas.mdl");
g_cl.m_local->SetModelIndex(iModel);
}
}
3. Goto FSN (clientdll.cpp)
C++:
// operator changer/ skinchanger
if (stage == FRAME_NET_UPDATE_POSTDATAUPDATE_START)
{
if (g_csgo.m_engine->IsInGame() && g_csgo.m_engine->IsConnected())
{
// Run operator changer, TODO
g_agents.SetupAgents();
}
}
create here extern boolean
extern bool LoadModel;
5. We need to reset our boolean now in event listener for example (or do it anywhere, maybe check for connected or ingame)
Goto events.cpp
Add to listener
C++:
add(XOR("player_spawned"), events::player_spawn);
C++:
void player_spawn(IGameEvent* evt);
C++:
// On spawn, map loaded
void events::player_spawn(IGameEvent* evt) {
if (!evt || !g_cl.m_local)
return;
if (!strcmp(evt->GetName(), "player_spawned"))
{
int spawned_player = g_csgo.m_engine->GetPlayerForUserID(evt->m_keys->FindKey(HASH("userid"))->GetInt());
if (spawned_player == g_csgo.m_engine->GetLocalPlayer())
{
//g_notify.add(tfm::format(XOR("Local player is alive\n")));
LoadModel = false; // setup agents per map change
}
}
}
C++:
Dropdown agent_change;
Checkbox enable_agent;
enable_agent.setup(XOR("enable agent changer"), XOR("enable_agent_model"));
RegisterElement(&enable_agent);
agent_change.setup(XOR("setup agent"), XOR("agent_changer"), { XOR("sas") });
RegisterElement(&agent_change);