Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

我想实现chand功能 #529

Closed
q52888940 opened this issue Jan 26, 2025 · 4 comments
Closed

我想实现chand功能 #529

q52888940 opened this issue Jan 26, 2025 · 4 comments

Comments

@q52888940
Copy link

q52888940 commented Jan 26, 2025

#include <meta_hooksv.h>
#include
#include
#include
#include
#include

// 配置和缓存存储
std::map<std::string, std::string> g_ArmsConfig;
std::map<std::string, model_t*> g_CachedArmsModels;

// 辅助函数:清理模型路径并转为小写
std::string GetCleanModelName(const char* path)
{
std::string modelName = path;

// 移除路径
size_t slashPos = modelName.find_last_of("/\\");
if (slashPos != std::string::npos)
    modelName = modelName.substr(slashPos + 1);

// 移除扩展名
size_t dotPos = modelName.find('.');
if (dotPos != std::string::npos)
    modelName = modelName.substr(0, dotPos);

// 转为小写
std::transform(modelName.begin(), modelName.end(), modelName.begin(), 
    [](unsigned char c){ return std::tolower(c); });

return modelName;

}

// 加载INI配置
void LoadArmsConfiguration()
{
const char* iniPath = "addons/metahook/arms_config.ini";
std::ifstream file(iniPath);

if (!file.is_open())
{
    gEngfuncs.Con_DPrintf("[ArmsConfig] 无法打开配置文件: %s\n", iniPath);
    return;
}

gEngfuncs.Con_DPrintf("[ArmsConfig] 正在加载配置文件...\n");

std::string line;
int lineNum = 0;
while (std::getline(file, line))
{
    lineNum++;
    
    // 清理行内容
    line.erase(line.find_last_not_of(" \t") + 1);
    line.erase(0, line.find_first_not_of(" \t"));
    
    // 跳过空行和注释
    if (line.empty() || line[0] == ';' || line[0] == '#')
        continue;
        
    // 解析键值对
    size_t eqPos = line.find('=');
    if (eqPos == std::string::npos)
    {
        gEngfuncs.Con_DPrintf("[ArmsConfig] 第%d行格式错误: 缺少等号\n", lineNum);
        continue;
    }
    
    std::string model = line.substr(0, eqPos);
    std::string arms = line.substr(eqPos + 1);
    
    // 清理键值
    model.erase(std::remove_if(model.begin(), model.end(), ::isspace), model.end());
    arms.erase(std::remove_if(arms.begin(), arms.end(), ::isspace), arms.end());
    
    if (model.empty() || arms.empty())
    {
        gEngfuncs.Con_DPrintf("[ArmsConfig] 第%d行键值无效\n", lineNum);
        continue;
    }
    
    // 统一小写
    std::transform(model.begin(), model.end(), model.begin(), ::tolower);
    g_ArmsConfig[model] = arms;
}

gEngfuncs.Con_DPrintf("[ArmsConfig] 已加载 %d 条配置\n", g_ArmsConfig.size());

}

// 获取缓存模型
model_t* GetCachedModel(const std::string& modelPath)
{
auto it = g_CachedArmsModels.find(modelPath);
if (it != g_CachedArmsModels.end())
return it->second;

model_t* pModel = IEngineStudio.Mod_ForName(modelPath.c_str(), false);
if (pModel)
{
    g_CachedArmsModels[modelPath] = pModel;
    gEngfuncs.Con_DPrintf("[ArmsConfig] 已缓存模型: %s\n", modelPath.c_str());
}
else
{
    gEngfuncs.Con_DPrintf("[ArmsConfig] 无法加载模型: %s\n", modelPath.c_str());
}

return pModel;

}

// 骨骼查找函数
int FindBoneIndex(studiohdr_t* pstudiohdr, const char* boneName)
{
if (!pstudiohdr)
return -1;

for (int i = 0; i < pstudiohdr->numbones; i++)
{
    mstudiobone_t* pBone = (mstudiobone_t*)((byte*)pstudiohdr + pstudiohdr->boneindex) + i;
    if (strcmp(pBone->name, boneName) == 0)
        return i;
}
return -1;

}

// 绑定手臂模型
static void AttachHandToWeapon(cl_entity_t* weapon, cl_entity_t* hand, model_t* armsModel)
{
if (!weapon || !hand || !armsModel)
return;

hand->model = armsModel;
hand->curstate.movetype = MOVETYPE_FOLLOW;
hand->curstate.aiment = weapon->index;

// 查找右手骨骼
studiohdr_t* pstudiohdr = (studiohdr_t*)weapon->model->cache.data;
int boneIndex = FindBoneIndex(pstudiohdr, "Bip01 R Hand");
if (boneIndex != -1)
{
    hand->curstate.controller[0] = boneIndex;
}

}

// Hooked StudioSetupModel
static void My_StudioSetupModel(int bodypart, void** ppbodypart, void** ppsubmodel)
{
cl_entity_t* entity = IEngineStudio.GetCurrentEntity();

// 仅处理玩家实体
if (!entity || !pmove || entity->index != pmove->player_index + 1)
{
    studio.StudioSetupModel(bodypart, ppbodypart, ppsubmodel);
    return;
}

// 验证模型数据
if (!entity->model || !entity->model->cache.data)
{
    studio.StudioSetupModel(bodypart, ppbodypart, ppsubmodel);
    return;
}

// 获取模型名称
std::string modelName = GetCleanModelName(entity->model->name);
auto configIt = g_ArmsConfig.find(modelName);
if (configIt == g_ArmsConfig.end())
{
    studio.StudioSetupModel(bodypart, ppbodypart, ppsubmodel);
    return;
}

// 加载手臂模型
model_t* pArmsModel = GetCachedModel(configIt->second);
if (!pArmsModel)
{
    studio.StudioSetupModel(bodypart, ppbodypart, ppsubmodel);
    return;
}

// 获取视图模型(手臂)
cl_entity_t* handEntity = gEngfuncs.GetViewModel();
if (handEntity)
{
    AttachHandToWeapon(entity, handEntity, pArmsModel);
}

// 继续原处理流程
studio.StudioSetupModel(bodypart, ppbodypart, ppsubmodel);

}

// 重新加载配置
void ReloadArmsConfig()
{
gEngfuncs.Con_Printf("[ArmsConfig] 重新加载配置...\n");
g_ArmsConfig.clear();
g_CachedArmsModels.clear();
LoadArmsConfiguration();
}

// 控制台命令
void Cmd_ReloadArmsConfig()
{
ReloadArmsConfig();
}

// Metahook初始化
void MetaHook_Init()
{
// 加载配置
LoadArmsConfiguration();

// 挂钩Studio函数
MetaHookSV_SetHook(IEngineStudio, StudioSetupModel, My_StudioSetupModel);

// 注册命令
gEngfuncs.pfnAddCommand("mh_reload_arms", Cmd_ReloadArmsConfig);

}

@g0g5
Copy link

g0g5 commented Jan 27, 2025

You don't even get your code formatted into code block decently.

@q52888940
Copy link
Author

你甚至没有将你的代码格式化为code block合适的格式。

现在可以了

@q52888940
Copy link
Author

我真的很需要这个,我认为这个类似gmod的功能成功可以帮大家为模型工作更轻松,特别是搬运那些骨骼手臂一样的模型时,但是我对编码能力不足,我打算不同的人物模型可以设置不同的手臂,有谁愿意一起做这个吗

@hzqst
Copy link
Owner

hzqst commented Jan 30, 2025

Stop posting AI generated randomshit.

不要往这里粘贴AI拉的屎。

@hzqst hzqst closed this as not planned Won't fix, can't repro, duplicate, stale Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants