You are not logged in.
Как поулчить название анимации и ее библиотеку в CLEO ?
Ну хотя бы название.
Подскажите пожалуйста.
Offline
Чо?
Про библиотеку так и не понял. А названия всех анимаций есть в сети.
Проще запустит Gta anim manager и открыть архив с анимациями и там увидеть все названия анимы с ее воспроизведением на экране.
Offline
Чо?
Про библиотеку так и не понял. А названия всех анимаций есть в сети.
Проще запустит Gta anim manager и открыть архив с анимациями и там увидеть все названия анимы с ее воспроизведением на экране.
Мне нужно в скрипте узнать какая анимация у игрока (или бота) сейчас проигруется.
При этом именно получать а не проверять вклучена такая анимка или нет
Last edited by Jack_Savage (24-02-2017 16:13)
Offline
Ну хотя бы название.
А хеш не хочешь?
Есть опкод
0611: is_char_playing_anim 2@ anim "LRGIRL_IDLE_TO_L0"
Он сверяет все анимации, прицепленные к клампу, по хешу названия.
Если не залезать в дебри, можно предположить, что имена анимаций нигде не сохраняются (вместо них - хеши).
Можно составить таблицу связок хеш-имя, но это уже выходит за рамки скриптинга.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Ну хотя бы название.
А хеш не хочешь?
Есть опкод
0611: is_char_playing_anim 2@ anim "LRGIRL_IDLE_TO_L0"Он сверяет все анимации, прицепленные к клампу, по хешу названия.
Если не залезать в дебри, можно предположить, что имена анимаций нигде не сохраняются (вместо них - хеши).
Можно составить таблицу связок хеш-имя, но это уже выходит за рамки скриптинга.
То есть нельзя узнать какая анимация проигруется на боте ?
Хоть какую то инфу...
ID, хеш, название....
Что то что можно потом сравнить с уже заготовленими значениям.
Какой язык не имеет значения C++ Cleo (так то на С++ надо но как то переведу).
Хочу что то типу как в сампе GetPlayerAnimation
Last edited by Jack_Savage (25-02-2017 16:55)
Offline
в Cped есть еще некоторые статусы анимы. Но наверно ты про это знеаешь...
Offline
в Cped есть еще некоторые статусы анимы. Но наверно ты про это знеаешь...
CPed +0x15C = Some anim states:
0 = landing from jump
61 = punching
102 = stopped
154 = sprint
205 = run
Это ?
Ну и как мне узнать какая анимация у игрока ?
Тут только 5 статусов и это статусы а не анимации. Я правильно понимаю ?
Last edited by Jack_Savage (25-02-2017 17:35)
Offline
int anim = *(int*)0xB6F5F0 + 0x15C;
Что то не работает даже
Offline
Через чит енджин посмотрел...
Я думал она меняется зависимо от анимации а оказалось том только эти 5 состояний :С
Offline
Вот пример с использованием plugin-sdk - вывод списка анимаций игрока.
Main.cpp
#include "plugin.h" #include "game_sa\common.h" #include "game_sa\CFont.h" #include "game_sa\CSprite2d.h" #include "game_sa\CKeyGen.h" #include <map> using namespace plugin; class AnimNamesViewer { public: AnimNamesViewer() { static std::map<unsigned int, std::string> animNamesMap; static CdeclEvent<AddressList<0x4CF2D8, H_CALL>, PRIORITY_AFTER, ArgPickN<char *, 0>, unsigned int(char *)> myStoreAnimNameEvent; myStoreAnimNameEvent += [](char *name) { animNamesMap[CKeyGen::GetUppercaseKey(name)] = name; }; Events::drawingEvent += [] { CPed *ped = FindPlayerPed(); if (ped && ped->m_pRwClump) { unsigned int numAnimations = RpAnimBlendClumpGetNumAssociations(ped->m_pRwClump); if (numAnimations > 0) { CSprite2d::DrawRect(CRect(SCREEN_COORD_RIGHT(310.0f), SCREEN_COORD(265.0f), SCREEN_COORD_RIGHT(40.0f), SCREEN_COORD(275.0f + 50.0f * numAnimations)), CRGBA(30, 30, 30, 255)); CFont::SetAlignment(ALIGN_LEFT); CFont::SetColor(CRGBA(255, 255, 255, 255)); CFont::SetOutlinePosition(0); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetFontStyle(FONT_MENU); CFont::SetProp(true); CFont::SetWrapx(SCREEN_COORD_MAX_X * 2); CFont::SetBackground(false, false); int counter = 0; CAnimBlendAssociation *association = RpAnimBlendClumpGetFirstAssociation(ped->m_pRwClump); while (association) { static char text[256]; sprintf(text, "%d. %s", counter + 1, animNamesMap[association->m_pAnimBlendHierarchy->m_hashKey].c_str()); if (association->m_wFlags & 0x10) strcat(text, " (P)"); CFont::SetScale(SCREEN_MULTIPLIER(0.6f), SCREEN_MULTIPLIER(1.2f)); float width = CFont::GetStringWidth(text, true, false); if(width > SCREEN_COORD(250.0f)) CFont::SetScale(SCREEN_MULTIPLIER(0.6f * SCREEN_COORD(250.0f) / width), SCREEN_MULTIPLIER(1.2f)); float baseY = SCREEN_COORD(300.0f) + SCREEN_COORD(50.0f) * counter; CFont::PrintString(SCREEN_COORD_RIGHT(300.0f), baseY - SCREEN_COORD(25.0f), text); CSprite2d::DrawRect(CRect(SCREEN_COORD_RIGHT(300.0f), baseY, SCREEN_COORD_RIGHT(50.0f), baseY + SCREEN_COORD(8.0f)), CRGBA(130, 130, 130, 255)); CSprite2d::DrawRect(CRect(SCREEN_COORD_RIGHT(300.0f), baseY, SCREEN_COORD_RIGHT(300.0f - association->m_fCurrentTime / association->m_pAnimBlendHierarchy->m_fTotalTime * 250.0f), baseY + SCREEN_COORD(6.0f)), CRGBA(210, 210, 210, 255)); association = RpAnimBlendGetNextAssociation(association); ++counter; } CFont::DrawFonts(); } } }; } } animNamesView;
При желании можно оформить в виде опкода.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Вот пример с использованием plugin-sdk - вывод списка анимаций игрока.
Main.cpp
#include "plugin.h" #include "game_sa\common.h" #include "game_sa\CFont.h" #include "game_sa\CSprite2d.h" #include "game_sa\CKeyGen.h" #include <map> using namespace plugin; class AnimNamesViewer { public: AnimNamesViewer() { static std::map<unsigned int, std::string> animNamesMap; static CdeclEvent<AddressList<0x4CF2D8, H_CALL>, PRIORITY_AFTER, ArgPickN<char *, 0>, unsigned int(char *)> myStoreAnimNameEvent; myStoreAnimNameEvent += [](char *name) { animNamesMap[CKeyGen::GetUppercaseKey(name)] = name; }; Events::drawingEvent += [] { CPed *ped = FindPlayerPed(); if (ped && ped->m_pRwClump) { unsigned int numAnimations = RpAnimBlendClumpGetNumAssociations(ped->m_pRwClump); if (numAnimations > 0) { CSprite2d::DrawRect(CRect(SCREEN_COORD_RIGHT(310.0f), SCREEN_COORD(265.0f), SCREEN_COORD_RIGHT(40.0f), SCREEN_COORD(275.0f + 50.0f * numAnimations)), CRGBA(30, 30, 30, 255)); CFont::SetAlignment(ALIGN_LEFT); CFont::SetColor(CRGBA(255, 255, 255, 255)); CFont::SetOutlinePosition(0); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetFontStyle(FONT_MENU); CFont::SetProp(true); CFont::SetWrapx(SCREEN_COORD_MAX_X * 2); CFont::SetBackground(false, false); int counter = 0; CAnimBlendAssociation *association = RpAnimBlendClumpGetFirstAssociation(ped->m_pRwClump); while (association) { static char text[256]; sprintf(text, "%d. %s", counter + 1, animNamesMap[association->m_pAnimBlendHierarchy->m_hashKey].c_str()); if (association->m_wFlags & 0x10) strcat(text, " (P)"); CFont::SetScale(SCREEN_MULTIPLIER(0.6f), SCREEN_MULTIPLIER(1.2f)); float width = CFont::GetStringWidth(text, true, false); if(width > SCREEN_COORD(250.0f)) CFont::SetScale(SCREEN_MULTIPLIER(0.6f * SCREEN_COORD(250.0f) / width), SCREEN_MULTIPLIER(1.2f)); float baseY = SCREEN_COORD(300.0f) + SCREEN_COORD(50.0f) * counter; CFont::PrintString(SCREEN_COORD_RIGHT(300.0f), baseY - SCREEN_COORD(25.0f), text); CSprite2d::DrawRect(CRect(SCREEN_COORD_RIGHT(300.0f), baseY, SCREEN_COORD_RIGHT(50.0f), baseY + SCREEN_COORD(8.0f)), CRGBA(130, 130, 130, 255)); CSprite2d::DrawRect(CRect(SCREEN_COORD_RIGHT(300.0f), baseY, SCREEN_COORD_RIGHT(300.0f - association->m_fCurrentTime / association->m_pAnimBlendHierarchy->m_fTotalTime * 250.0f), baseY + SCREEN_COORD(6.0f)), CRGBA(210, 210, 210, 255)); association = RpAnimBlendGetNextAssociation(association); ++counter; } CFont::DrawFonts(); } } }; } } animNamesView;http://i.imgur.com/d2DHIZjm.jpg
При желании можно оформить в виде опкода.
Cпасибо, я не хочу юзать plugin sdk просто я не понимаю что там и как вообще...
Ну хотя...
unsigned int numAnimations = RpAnimBlendClumpGetNumAssociations(ped->m_pRwClump);
Это я так понимаю id, hash или что то там... что меняется зависимо от анимации ?
Offline
Cпасибо, я не хочу юзать plugin sdk просто я не понимаю что там и как вообще...
Ну тогда не знаю, как тебе ещё помочь
Такой код
*(int*)0xB6F5F0 + 0x15C;
я писать не буду.
Могу опкодами сделать, разве что.
int numAnimations = RpAnimBlendClumpGetNumAssociations(ped->m_pRwClump);
Эта функция получает кол-во активных анимаций, прицепленных к клампу.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Cпасибо, я не хочу юзать plugin sdk просто я не понимаю что там и как вообще...
Могу опкодами сделать, разве что.
Опкодом узнать какая анимация ?
Или сделать перепод если (там выше писали опкод) такая то анимация то возвращаем что то.
Я опкодом ищу уже 4 день
Offline
Можно сделать новый опкод в .cleo-плагине.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Можно сделать новый опкод в .cleo-плагине.
Оу... Нечего не понятно
Offline
http://cleo.li/ru/plugins.html
CLEO 4 позволяет создавать новые опкоды, используя исходные коды CLEO SDK. В стартовом комплекте библиотеки можно найти три примера таких плагинов:
IniFiles.cleo - работа с INI файлами;
FileSystemOperations.cleo - работа с файлами и папками.
IntOperations.cleo - битовые операции над целыми числами (AND, OR, XOR, и т.д.).
#include "plugin.h" #include "CLEO.h" #include "game_sa\CPools.h" #include "game_sa\common.h" #include "game_sa\CKeyGen.h" #include <map> using namespace plugin; /* SASCM.ini 1A01=2,%2d% = get_char %1d% num_of_active_animations 1A02=2,%2d% = get_char %1d% active_animations 1A03=2,%2d% = get_char %1d% main_active_animation opcodes.txt 1A01: 0@ = get_char 1@ num_of_active_animations 1A02: 0@v = get_char 1@ active_animations 1A03: 0@v = get_char 1@ main_active_animation */ class GetPedAnimationOpcodes { public: static char animNameGlobalName[1024]; static std::map<unsigned int, std::string> animNamesMap; static CdeclEvent<AddressList<0x4CF2D8, H_CALL>, PRIORITY_AFTER, ArgPickN<char *, 0>, unsigned int(char *)> myStoreAnimNameEvent; static void MyStoreAnimName(char *name) { animNamesMap[CKeyGen::GetUppercaseKey(name)] = name; } // 1A01: 0@ = get_char 1@ num_of_active_animations static OpcodeResult WINAPI Opcode_GetPedNumberOfActiveAnimations(CScriptThread *thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); if (ped && ped->m_pRwClump) CLEO_SetIntOpcodeParam(thread, RpAnimBlendClumpGetNumAssociations(ped->m_pRwClump)); else CLEO_SetIntOpcodeParam(thread, 0); return OR_CONTINUE; } // 1A02: 0@v = get_char 1@ active_animations static OpcodeResult WINAPI Opcode_GetPedAnimationsNames(CScriptThread *thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); animNameGlobalName[0] = '\0'; if (ped && ped->m_pRwClump) { CAnimBlendAssociation *association = RpAnimBlendClumpGetFirstAssociation(ped->m_pRwClump); if(association){ strcpy_s(animNameGlobalName, animNamesMap[association->m_pAnimBlendHierarchy->m_hashKey].c_str()); for (association = RpAnimBlendGetNextAssociation(association); association; association = RpAnimBlendGetNextAssociation(association)) { strcat_s(animNameGlobalName, ","); strcat_s(animNameGlobalName, animNamesMap[association->m_pAnimBlendHierarchy->m_hashKey].c_str()); } } } int paramType = CLEO_GetOperandType(thread); if (paramType == localVarVString || paramType == localVarSString) CLEO_WriteStringOpcodeParam(thread, animNameGlobalName); else CLEO_SetIntOpcodeParam(thread, reinterpret_cast<int>(animNameGlobalName)); return OR_CONTINUE; } // 1A03: 0@v = get_char 1@ main_active_animation static OpcodeResult WINAPI Opcode_GetPedMainAnimationName(CScriptThread *thread) { CPed *ped = CPools::GetPed(CLEO_GetIntOpcodeParam(thread)); animNameGlobalName[0] = '\0'; if (ped && ped->m_pRwClump) { CAnimBlendAssociation *association = RpAnimBlendClumpGetMainAssociation(ped->m_pRwClump, NULL, NULL); if(association) strcpy_s(animNameGlobalName, animNamesMap[association->m_pAnimBlendHierarchy->m_hashKey].c_str()); } int paramType = CLEO_GetOperandType(thread); if (paramType == localVarVString || paramType == localVarSString) CLEO_WriteStringOpcodeParam(thread, animNameGlobalName); else CLEO_SetIntOpcodeParam(thread, reinterpret_cast<int>(animNameGlobalName)); return OR_CONTINUE; } GetPedAnimationOpcodes() { CLEO_RegisterOpcode(0x1A01, Opcode_GetPedNumberOfActiveAnimations); CLEO_RegisterOpcode(0x1A02, Opcode_GetPedAnimationsNames); CLEO_RegisterOpcode(0x1A03, Opcode_GetPedMainAnimationName); myStoreAnimNameEvent.Add(MyStoreAnimName); } } pedAnimOpcodes; char GetPedAnimationOpcodes::animNameGlobalName[1024]; std::map<unsigned int, std::string> GetPedAnimationOpcodes::animNamesMap; CdeclEvent<AddressList<0x4CF2D8, H_CALL>, PRIORITY_AFTER, ArgPickN<char *, 0>, unsigned int(char *)> GetPedAnimationOpcodes::myStoreAnimNameEvent;
{$CLEO} {$OPCODE 1A01=2,%2d% = get_char %1d% num_of_active_animations} {$OPCODE 1A02=2,%2d% = get_char %1d% active_animations} {$OPCODE 1A03=2,%2d% = get_char %1d% main_active_animation} thread 'ANIMOPC' while true wait 0 if 0256: is_player_playing 0 then 01F5: get_player_char 0 store_to 0@ 1A02: 1@ = get_char 0@ active_animations 0ACC: print_string 1@ time 100 end end
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Та блин... Мне уже даже стыдно что из за меня время на написание или поиск этого потратили.
Я хочу это сделать для ванильной игры.
Вот что именно хочу:
https://youtu.be/38VXY0MMjRU
Делать нечего было... Занимался всякой фигней.
Ну вот хочу сделать синхру ботов.
Типу пишешь в чат команду или какую то кнопку нажымаешь (ну это уже сам сделаю)
И появляется куча ботов которые делают все тоже что и ты. При этом чтобы работало и в сампе и в одиночке.
Думал тупо получать анимку игрока и в цикле ее включать всем ботам.
Сначала думал с исходников сампа взять но там мало того что не понятно так и сделано все под клиент и сервер а мне надо без сервера.
Ну и делаю я это все без плагинов типу вашего.
Даже без библиотеки клео.
Так что мне этот код немного безполезен так как я ее не использую :С
А чтобы получать анимацию я так понял нужно ставить хук на функцию включения анимки и когда игра пытается включить анимку то в том хуке ловить анимку ?
Если да то я это точно не сделаю.
Из собейта фупа или чей он там... Собейт который на asi я 2 дня доставал уже готовы хук на DirectX ибо не мог понять как он вообще работать.
Last edited by Jack_Savage (26-02-2017 10:19)
Offline
Хук ставится в место, где название анимации "переводится" в хеш. Делаем это для того, чтобы иметь возможность "перевести" хеш обратно в название (сохраняем название в карту с ключом-хешем).
static CdeclEvent<AddressList<0x4CF2D8, H_CALL>, PRIORITY_AFTER, ArgPickN<char *, 0>, unsigned int(char *)> myStoreAnimNameEvent; // Хук myStoreAnimNameEvent += [](char *name) { animNamesMap[CKeyGen::GetUppercaseKey(name)] = name; // Сохраняем в карту };
Получаем кол-во активных анимаций педа. Одновременно пед может проигрывать несколько анимаций (например - стоит и прицеливается)
unsigned int numAnimations = RpAnimBlendClumpGetNumAssociations(ped->m_pRwClump); if (numAnimations > 0) { // Если есть анимации
Получаем описание первой анимации
CAnimBlendAssociation *association = RpAnimBlendClumpGetFirstAssociation(ped->m_pRwClump);
Переводим хеш в название, используя нашу карту
sprintf(text, "%d. %s", counter + 1, animNamesMap[association->m_pAnimBlendHierarchy->m_hashKey].c_str());
В цикле получаем следующую анимацию, таким образом, "проходимся" по всем анимациям.
association = RpAnimBlendGetNextAssociation(association);
Ну и, если пишешь код C++ - надо искать хотя бы уроки в интернете и разбираться.
Last edited by DK22Pac (26-02-2017 10:52)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
В ванильной - это как?
Ты код в main.scm пишешь?
Нет. Опкоды я визываю через SCM hook в C++ (аля asi) но не хочу юзать плагины.
Offline
И еще.
m_pRwClump от куда берется ?
Это id актера или что ?
Offline
PS: Спасибо вам за ваш код.
Я тут в MTA нашел... Вашу функцию вот пробую перенести себе ее)
typedef struct RpClump RpClump; typedef RpClump *(*RpClumpCallback) (RpClump * clump, void *data); struct RwObject { unsigned char type; unsigned char subtype; unsigned char flags; unsigned char privateFlags; void *parent; // should be RwFrame with RpClump }; struct RwListEntry { RwListEntry *next, *prev; }; struct RwList { RwListEntry root; }; struct RpClump { // RenderWare (plugin) Clump (used by GTA) RwObject object; RwList atomics; RwList lights; RwList cameras; RwListEntry globalClumps; RpClumpCallback callback; }; list < CAnimBlendAssociation * > m_Associations; CAnimBlendAssociation * GetAnimBlendAssociation(CAnimBlendAssociationSAInterface * pInterface) { if (pInterface) { list < CAnimBlendAssociation * > ::iterator iter = m_Associations.begin(); for (; iter != m_Associations.end(); iter++) { if ((*iter)->GetInterface() == pInterface) { return *iter; } } CAnimBlendAssociation * pAssociation = new CAnimBlendAssociationSA(pInterface); m_Associations.push_back(pAssociation); return pAssociation; } return NULL; } CAnimBlendAssociation * RpAnimBlendClumpGetFirstAssociation(RpClump * pClump) { if (!pClump) return NULL; CAnimBlendAssociationSAInterface * pInterface; DWORD dwFunc = FUNC_RpAnimBlendClumpGetFirstAssociation; _asm { push pClump call dwFunc mov pInterface, eax add esp, 0x4 } return GetAnimBlendAssociation(pInterface); }
VS собрала это без ошибок. Для меня это уже достижение
Еще бы сказали где взять RpClump и тогда пробовал или работает это
Last edited by Jack_Savage (26-02-2017 13:54)
Offline
Нет. Опкоды я визываю через SCM hook в C++
Что значит "аля asi"? Это динамическая библиотека? Чем она подгружается, если не asi-loader'ом?
Кламп это графический обьект RenderWare.
"Взять" его можно в plugin-sdk, подключив хедер RenderWare.h.
Можешь выложить проект со своим плагином, я тебе помогу подключить туда библиотеку и хедеры plugin-sdk.
Last edited by DK22Pac (28-02-2017 19:40)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Нет. Опкоды я визываю через SCM hook в C++
Что значит "аля asi"? Это динамическая библиотека? Чем она подгружается, если не asi-loader'ом?
Кламп это графический обьект RenderWare.
"Взять" его можно в plugin-sdk, подключив хедер RenderWare.h.
Можешь выложить проект со своим плагином, я тебе помогу подключить туда библиотеку и хедеры plugin-sdk.
А не прийдется переписывать мод ? И еще.
Как бы... Я может немного тупой но я не нашел где файл plugin.lib (точно не помню) на гите
Это динамическая библиотека? Чем она подгружается, если не asi-loader'ом?
Да и еще раз да
Last edited by Jack_Savage (28-02-2017 20:06)
Offline
plugin.lib получается после сборки проекта plugin_sa в решении plugin-sdk.
Last edited by DK22Pac (28-02-2017 20:49)
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
plugin.lib получается после сборки проекта plugin_sa в решении plugin-sdk.
Ну буду пробовать подкруть.
А нельзя создавать опкодом бота и через ваш плагин узнавать анимацию ?
Просто там переделать дофига прийдется
PS: Спасибо :3
С ошибками разобрался.
Но есть к вам вопросик.
Если в моем мод есть хук d3d9 и у вас в plugin sdk есть я так понимаю d3d9 хук...
Они же не будут ругаться и выдавать непонятную картинку ?
Еще раз спасибо :3
Last edited by Jack_Savage (28-02-2017 22:05)
Offline