Не вижу развития проекта дальше, т.к. не могу воскресить слаеров. Что только не перепробовал. А функции IssueTrainOrderByIdBJ нету в нативных функциях, которые достаю с помощью JassApi.dll. Есть аналоги IssueImmediateOrderById и IssueNeutralImmediateOrderById, но в данной карте срабатывает только 2 приказа на слерку вообще, которые не воскрешают слаера это 851980, 851978 другие отсеиваю такие как: ID_ORDER_STOP, ID_ORDER_HOLDPOSITION, ID_ORDER_PATROL, ID_ORDER_ATTACK, ID_ORDER_SMART, ID_ORDER_MOVE, ID_ORDER_CANCEL, и стан 851973, которые тоже срабатывают на слерку, но от них нет ни какого толку для воскрешения слаера. По Id юнита тоже побывал воскрешать слаера, как в массиве так и без, и по TypeId. Никакого толку. Если кто разберётся, как воскрешать слаера в данной карте сообщите.
IceFog, а ты сможешь сделать перед запуском файла .json определитель ОС и разрядности архитектуры, чтобы запустить разные файлы .json. Это нужно для загрузки на машинах x86 библиотек x86 и x64 соответственно для функций <boost>.
Варкрафт 3 всегда х86 (не считая рефу), какой толк от х64, если его х86 приложения всё-равно не поймут?
IceFog, а ты сможешь сделать перед запуском файла .json определитель ОС и разрядности архитектуры, чтобы запустить разные файлы .json. Это нужно для загрузки на машинах x86 библиотек x86 и x64 соответственно для функций <boost>.
Если нативка зарегистрирована, то виртуальная машина JASS'а сможет её использовать.
Учитывая, что и обычный и ИИ скрипты исполняются ею, то почему бы и нет?
Единственная проблема — регистрация должна произойти до компиляции, а иначе компилятор откажется работать, сетуя на несуществующую нативку.
Буду благодарен за пример.
Я добавляю свою нативку в common.ai
native fBeginGameProcessAI takes nothing returns integer
Запускаю её у человека human,ai
call fBeginGameProcessAI()
Инициализирую библиотеку до:
call InitBlizzard()
call MeleeStartingAI()
И скрипт ИИ не работает.
Или её надо редеректом вызывать?
Просто на некоторых машинах у меня не получается запустить .mix файл где установлен лицензионный Windows 10. А если подгружать через карту, то работает на этой машине.
Складывается такое впечатление, будто ты не писал прежде на JASS'е, а иначе почему даже простое создание юнита вызывает у тебя проблемы?
Попробуй сначала почитать статьи и сделать простенькую карту на нём или изучить уже существующие, а уже потом на C++ перейти как окрепнешь.
Переслать команду от одного ИИ другому ИИ помоги в таких то координатах и 4 точки переслать которые прописаны в DLL. Я так думаю только с помощью сообщений можно это сделать. Мне чистый бот на JASS'e не нужен.
IceFog, можешь объяснить, как запустить только один экземпляр библиотеки при загрузке карты, как у тебя в Example.dll, чтобы не было дизсинхронизации, только на С++. Аналог твоего запуска библиотеки на паскале:
begin
InitCamera;
InitSpell;
CreateAngryWorker;
CreateMeat;
end.
Пробывал следующий код:
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call != DLL_PROCESS_ATTACH) return TRUE;
DisableThreadLibraryCalls(hModule);
if (fRegistrJassApi() == FALSE) return TRUE;
if (fRegistrNatives() == FALSE) return TRUE;
HUNIT u;
u = CreateUnit(GetLocalPlayer(),ID_UNIT_MAIN_HUMAN1,0,0,0);
IssuePointOrder(u,"move",1000,1000);
return TRUE;
}
Он запускается на обоих машинах. Как перевести с паскаля на С++ твой Example.dll?
Unryze, у меня получилось с помощью в этой статьи xgm.guru/p/wc3/anyscript (Сценарий на любом языке) поиграть по сети со своей dll'кой. Это и есть мемхак?
IceFog,
cdecl (C calling convention)
Стандартное соглашение о вызовах для программ на C/C++.
В данном соглашение аргументы передаются справа налево и кладутся на стек, как и в [[#STDCALL Standart Calling Convention|stdcall]], возвращаемое значение кладется в регистр EAX. Но вот стек уже очищается функцией, которая вызывает. Имена функций начинаются с символа нижнего подчеркивания, без указания количества байт для аргументов к конце.
stdcall (Standart Calling Convention)
STDCALL это стандартное соглашение для Win32 API. В данном соглашение, аргументы передаются справа налево и очистка стека ложится на вызываемую функцию. Для передачи аргументов используется стек, т.е. перед вызовом нужно положить аргументы на стек. Возвращаемое значение записывается в регистр eax.
КОРОЧЕ, РАЗНИЦА:
__cdecl - очистку стека производит вызывающая программа (*). Основной способ вызова для Си. Это основной способ вызова функций с переменным числом аргументов.
__stdcall (он же winapi) - очистку стека производит вызываемая подпрограмма. (**). Применяется при вызове функций WinAPI.
Даже в твоём коде файла moduleutils.pas используется stdcall:
unit ModuleUtils;
interface
const
JASS_API_DLL_NAME = 'JassApi.dll';
type
PJassString = Pointer;
TJassStringHandle = longword;
TJassFunctionHandle = longword;
TJassHandle = longword;
TSingle = record Value: Single end;
function GetJassNative(Name: PChar): Pointer; stdcall; external JASS_API_DLL_NAME;
function GetStringHandle(Value: PChar): TJassStringHandle; stdcall; external JASS_API_DLL_NAME;
function GetStringFromHandle(StringHandle: TJassStringHandle): PChar; stdcall; external JASS_API_DLL_NAME;
function GetJassString(Value: PChar): PJassString; stdcall; external JASS_API_DLL_NAME;
function GetJassStringContent(JassString: PJassString): PChar; stdcall; external JASS_API_DLL_NAME;
implementation
end.
Ev3nt,
*(BYTE*) (GameDll + 0x2de2a0+ 0x0) = 0xE8;
*(DWORD*) (GameDll + 0x2de2a0+ 0x1) = (DWORD)hookCHS - (dwGameBaseAddress + 0x2de2a0+ 0x5);
*(BYTE*) (GameDll + 0x2de2a0+ 0x5) = 0xC3;
Тут что два одинаковых адреса в разных переменных? В GameDll и в dwGameBaseAddress?
» WarCraft 3 / Генератор карт VF
» WarCraft 3 / Генератор карт VF
» WarCraft 3 / Пятиминутка в вампов
» WarCraft 3 / Генератор карт VF
» WarCraft 3 / Пятиминутка в вампов
Отредактирован Vampir_kolik
» XGM — Премия года / Премия 2023 года
» WarCraft 3 / Сценарий на любом языке
» WarCraft 3 / Сценарий на любом языке
» WarCraft 3 / Сценарий на любом языке
Отредактирован Vampir_kolik
» WarCraft 3 / Работа с нативными функциями
Я добавляю свою нативку в common.ai
native fBeginGameProcessAI takes nothing returns integer
Запускаю её у человека human,ai
call fBeginGameProcessAI()
Инициализирую библиотеку до:
call InitBlizzard()
call MeleeStartingAI()
И скрипт ИИ не работает.
Или её надо редеректом вызывать?
» WarCraft 3 / Сценарий на любом языке
» WarCraft 3 / Работа с нативными функциями
» WarCraft 3 / Сценарий на любом языке
» WarCraft 3 / Сценарий на любом языке
» WarCraft 3 / Сценарий на любом языке
» WarCraft 3 / Сценарий на любом языке
» WarCraft 3 / Работа с нативными функциями
» WarCraft 3 / Работа с нативными функциями
» WarCraft 3 / Работа с нативными функциями
» WarCraft 3 / Ускоренная виртуальная машина
» WarCraft 3 / Своя нативка на С++
» WarCraft 3 / Своя нативка на С++
» WarCraft 3 / Своя нативка на С++
Отредактирован Vampir_kolik
» WarCraft 3 / Своя нативка на С++
cdecl (C calling convention)
Стандартное соглашение о вызовах для программ на C/C++.
STDCALL это стандартное соглашение для Win32 API. В данном соглашение, аргументы передаются справа налево и очистка стека ложится на вызываемую функцию. Для передачи аргументов используется стек, т.е. перед вызовом нужно положить аргументы на стек. Возвращаемое значение записывается в регистр eax.
__cdecl - очистку стека производит вызывающая программа (*). Основной способ вызова для Си. Это основной способ вызова функций с переменным числом аргументов.
__stdcall (он же winapi) - очистку стека производит вызываемая подпрограмма. (**). Применяется при вызове функций WinAPI.
» WarCraft 3 / Вызов функций вк 3, через mix (dll)
*(BYTE*) (GameDll + 0x2de2a0+ 0x0) = 0xE8;
*(DWORD*) (GameDll + 0x2de2a0+ 0x1) = (DWORD)hookCHS - (dwGameBaseAddress + 0x2de2a0+ 0x5);
*(BYTE*) (GameDll + 0x2de2a0+ 0x5) = 0xC3;
Тут что два одинаковых адреса в разных переменных? В GameDll и в dwGameBaseAddress?