Объявления
Поздравляем
Roman2211


Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

Как создать плагин для HD мода

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

Re: Как создать плагин для HD мода

Сообщение Rolex » 30 янв 2021, 16:26

Кстати, заметил, что в Заброшенной шахте с Троглодитами нет разбивки на отряди в диалоге при посещении. Хотя в данном случае (в Заброшенной шахте) даже без посещения по ПКМ всегда отображается размер охраны: (100-249) Троглодиты. Но как правило отрядов несколько и среди них обязательно есть один улучшенный отряд (Адские троглодиты), но по ПКМ мы видим только Троглодитов. :smile1:

По-моему, это баг, вроде того, как мы нападем на какой-то неулучшенный отряд существ и среди них попадается один улучшенный. Либо же это неверный вывод охраны по ПКМ. Тогда нужно править сам текст сообщения по ПКМ и делать, как с банками существ, где будет отображаться размер охраны улучшенных и неулучшенных существ одного уровня. Интересно, но SoD_SP с существами баг фиксит, а с Заброшенной шахтой НЕТ.

 Скрины:
Изображение Изображение Изображение

Но самое интересное, что улучшенный стек есть как в HD+, так и вместе с подключенным SoD_SP. Но как только к ним подключаешь еще Englification 1.1 со всеми оригинальными (на англ) картами из Complete под русскую версию Героев, улучшеный стек исчезает. Пока не ясно почему так происходит...

PS: По ходу разобрался. Отключил SoD_SP и проверил вместе с Englification 1.1 и улучшенного стека НЕТ. Но у меня Englification_Pack с англ картам из GOG, а юзается русская версия с картами от Буки (там всегда будет один улучшенный отряд существ). Попробовал подтянуть эту же тестовую карту с подключенным Englification_Pack, но с переводом от Буки и получил один улучшенный стек. Проверил и наоборот, оригинальную англ карту на русской версии от Буки без каких-либо плагинов, - улучшенного отряда НЕТ. Получается, что с оригинальными картами, улучшенного отряда не будет никогда, как и должно быть. Проблема в самих русскоязычных картах от Буки. То есть это косяк Буки, когда они переводили карты, они еще и свои изменения туда вносили!

То есть получается, что для Банков существ один грейдженный стек с некой вероятностью - это норма. В то время как для Заброшенной шахты подобного быть не должно, но на русскоязычных картах от Буки мы подобное получаем. Получается, что все равно проверку на грейженный стек нужно делать, ибо мы не знаем кто на какой карте играет (англ или рус).
***
AlexSpl, а можно ли в последнюю версию нашего кода добавить в диалог посещения Заброшенной шахты разбивку на отряды с их интервальным количеством?

PS2: И, по ходу, остается еще и Пирамида не сделанная. Там вообще все в комплексе нужно... В диалоге посещения - разбивка на отряды (Алмазные големы: 10-19; Алмазные големы: 10-19; Золотые големы: 20-49), в диалоге по ПКМ после посещения, но отказа от боя общее количество без разбивки (Толпа (20-49) Алмазные големы, и толпа (20-49) Золотые големы из ARRAYTXT), и, получается, убирать диалог при посещении, если Пирамидка уже разграбленная... :smile5:

И, наверное, для жилищ 5-7+ уровня после посещения (и Фабрика големов, как исключение: Мало (5-9) Алмазные големы, и мало (5-9) Золотые големы), но отказа от боя, надо бы, чтобы по ПКМ также можно было видеть охрану, как со Склепом (Под охраной: Пара(1-4) или Мало (5-9)).
Последний раз редактировалось Rolex 31 янв 2021, 16:08, всего редактировалось 18 раз(а).
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 30 янв 2021, 16:57

Цитата:
AlexSpl, а можно ли в последнюю версию нашего кода добавить в диалог посещения Заброшенной шахты разбивку на отряды с их интервальным количеством?

Можно. Я писал, как найти, на сколько отрядов поделятся нейтралы и будет ли среди них улучшенный отряд. Позже посмотрю свой код.
Вернуться к началу

offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

Re: Как создать плагин для HD мода

Сообщение RoseKavalier » 31 янв 2021, 02:05

Rolex писал(а):

PS: По ходу разобрался. Отключил SoD_SP и проверил вместе с Englification 1.1 и улучшенного стека НЕТ. Но у меня Englification_Pack с англ картам из GOG, а юзается русская версия с картами от Буки (там всегда будет один улучшенный отряд существ). Попробовал подтянуть эту же тестовую карту с подключенным Englification_Pack, но с переводом от Буки и получил один улучшенный стек. Проверил и наоборот, оригинальную англ карту на русской версии от Буки без каких-либо плагинов, - улучшенного отряда НЕТ. Получается, что с оригинальными картами, улучшенного отряда не будет никогда, как и должно быть. Проблема в самих русскоязычных картах от Буки. То есть это косяк Буки, когда они переводили карты, они еще и свои изменения туда вносили!


Somewhere around HDmod 4.2 (I forget the exact id), Baratorch changed the seed and RNG of battles with wandering creatures in HD+, changing both stack splits, upgraded creatures, obstacles...
If you use SoD_SP to restore original RNG then it shows up as the original game would have it. The stack split preview algorithm only uses the vanilla formulas, so it may appear erroneous depending on your settings.
Finally, you are correct, I never implemented split on Abandoned Mines (and Pyramids), just the amount of creatures present. Guess I should do it as well!
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 02 фев 2021, 20:22

Код, который по правому клику на Заброшенную шахту показывает кол-во стеков, на которое разобьются защитники, а также появится ли среди них улучшенный отряд. Код для примера. Вы можете попробовать сами его доработать, чтобы он выводил информацию о кол-ве существ в каждом отряде (у Вас есть кол-во существ и кол-во стеков), а также учитывал тот случай, когда грейд есть, а отряд только один (в игре отряд неулучшенных нейтралов не может получить улучшенный стек при разбиении на 1 стек), и считал, в какой позиции окажется улучшенный стек (в FizMiG'е есть, вроде, но и так понятно, что посередине - при нечётном кол-ве отрядов и на полслота :smile1: ниже - при чётном). Также этот код легко доработать, чтобы он показывал аналогичную информацию о разбиении нейтралов на стеки.

Тип __int64 нужен для точности. Можно через дробные числа, и я делился такими коэффициентами, но я их округлил до значений, которых заведомо хватит для карт 144x144, однако ниже приведён код, который должен работать и для карт 252x252 (используется в LMOracle). Эти коэффициенты - результат упрощения вычислений алгоритма ГПСЧ при фиксированном Seed и следующих за ними.

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "..\..\HotA\homm3.h"
#include <string>

using namespace std;

Patcher* _P;
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

#define o_CreatureInfo ((_CreatureInfo_*)0x6703B8)

string getInterval(int n)
{
    string str;
    if ( n < 1 ) str = "0"; else
    if ( n < 5 ) str = "1-4"; else
    if ( n < 10 ) str = "5-9"; else
    if ( n < 20 ) str = "10-19"; else
    if ( n < 50 ) str = "20-49"; else
    if ( n < 100 ) str = "50-99"; else
    if ( n < 250 ) str = "100-249"; else
    if ( n < 500 ) str = "250-499"; else
    if ( n < 1000 ) str = "500-999"; else str = "1000+";
    return str;
}

_MapItem_* mapItem;
int __stdcall saveObjEntranceAddr(LoHook* h, HookContext* c)
{
    mapItem = (_MapItem_*)c->eax;
   
    return EXEC_DEFAULT;
}

// Получаем указатель на _Dwelling_ по ID жилища существ
_Dwelling_* GetDwelling(_int_ dwellingId) {
    return (_Dwelling_ *)(o_GameMgr->Field<int>(0x4E39C) + 92 * dwellingId);
}

int __stdcall Crypt_SkipMsgIfVisited(LoHook* h, HookContext* c)
{
   if ( *(int*)*(int*)(c->ebp + 0xC) & 0x2000000 )
   {
      c->return_address = 0x4AC1E5;
      return NO_EXEC_DEFAULT;
   }

   return EXEC_DEFAULT;
}

int getStacksCount(double k, char x, char y, char z)
{
    __int64 devCoef[] = {0x5C6F80EB, 0xC8374AB9, 0x73D409E3, 0xBD38DECE};
   
    int n = 2;
    if ( k < 0.50 ) n = 7; else
    if ( k < 0.67 ) n = 6; else
    if ( k < 1.00 ) n = 5; else
    if ( k < 1.50 ) n = 4; else
    if ( k < 2.00 ) n = 3;
   
    // Deviation
    __int64 splitValue = (((devCoef[0] * x + devCoef[1] * y + devCoef[2] * z + devCoef[3]) >> 0x10) & 0x7FFF) % 100 + 1;
    if ( splitValue <= 20 ) --n;
    if ( splitValue >= 80 && n < 7 ) ++n;

    return n;
}

bool upgradedStack(double k, char x, char y, char z)
{
    __int64 upgCoef[] = {0x0BB0E93F, 0x375E43D5, 0x14CD2E57, 0x8014BA59};

    return (((upgCoef[0] * x + upgCoef[1] * y + upgCoef[2] * z + upgCoef[3]) >> 0x10) & 0x7FFF) % 100 < 50;
}

int __stdcall showGuards(LoHook* h, HookContext* c)
{
    // Получаем состояние банка
    _MapItem_* mapItem = (_MapItem_*)*(int*)(c->ebp + 0xC);
   
    if ( mapItem ) // Перестраховываемся, но можно и без этой проверки
    {
        _CrBankState_* bankState = CALL_1(_CrBankState_*, __fastcall, 0x405D80, mapItem);
       
        string str = (char*)c->ecx; // Оригинальное сообщение
        str += "\n";
           
        for (int i = 0; i < bankState->defenders.GetStacksCount(); ++i)
            str = str + "\n" + o_CreatureInfo[bankState->defenders.type[i]].name_plural + ": " +
            getInterval(bankState->defenders.count[i]);
               
        // Передаём адрес текстового буфера в качестве аргумента для диалога
        sprintf(o_TextBuffer, "%s", str.c_str());
        c->ecx = (int)o_TextBuffer;

        mapItem->SetAsVisited(o_GameMgr->GetMeID());
    }
   
    return EXEC_DEFAULT;
}

int __stdcall showMonsters(LoHook* h, HookContext* c)
{
    // Получаем состояние жилища
    _MapItem_* mapItem = (_MapItem_*)*(int*)(c->ebp + 0xC);

    if ( mapItem ) // Перестраховываемся, но можно и без этой проверки
    {
        string str = (char*)c->ecx; // Оригинальное сообщение
        str += "\n";

        // Получаем состояние жилища существ
        _Dwelling_* dwelling = GetDwelling(mapItem->setup);

        // Если мы владельцы, показываем количество существ
        if ( dwelling && dwelling->owner_ix == o_GameMgr->GetMeID() )
        {
            string str = (char*)c->ecx; // Оригинальное сообщение
            str += "\n";

            for (int i = 0; i < 4; ++i)
                if ( dwelling->creature_types[i] != ID_NONE )
                    str = str + "\n" + o_CreatureInfo[dwelling->creature_types[i]].name_plural + ": " +
                    getInterval(dwelling->creature_counts[i]);

            // Передаём адрес текстового буфера в качестве аргумента для диалога
            sprintf(o_TextBuffer, "%s", str.c_str());
            c->ecx = (int)o_TextBuffer;
        }
    }
   
    return EXEC_DEFAULT;
}

int __stdcall showRefugeeCamp(LoHook* h, HookContext* c)
{
    // Получаем состояние жилища
    _MapItem_* mapItem = (_MapItem_*)*(int*)(c->ebp + 0xC);

    if ( mapItem ) // Перестраховываемся, но можно и без этой проверки
    {
        // Передаём адрес текстового буфера в качестве аргумента для диалога
        sprintf(o_TextBuffer, "%s\n\n%s: %s", (char*)c->ecx, o_CreatureInfo[mapItem->os_type].name_plural, getInterval(mapItem->setup).c_str());
        c->ecx = (int)o_TextBuffer;
    }
   
    return EXEC_DEFAULT;
}

int __stdcall showGuardsRMB(LoHook* h, HookContext* c)
{
    if ( mapItem )
    {
        // Банки существ
        if ( mapItem->IsVisited(o_GameMgr->GetMeID()) )
        {
            // mapItem->object_type = 0x10 - стандартные банки, 0x18 - Derelict Ship, 0x19 - Dragon Utopia, 0x54 - Crypt, 0x55 - Shipwreck
            if ( mapItem->object_type == 0x10 || mapItem->object_type == 0x18 || mapItem->object_type == 0x19 ||
                 mapItem->object_type == 0x54 || mapItem->object_type == 0x55 )
            {
                // Получаем состояние банка
                _CrBankState_* bankState = CALL_1(_CrBankState_*, __fastcall, 0x405D80, mapItem);

                string str = (char*)c->ecx; // Оригинальное сообщение
                str += "\n";

                for (int i = 0; i < bankState->defenders.GetStacksCount(); ++i)
                    str = str + "\n" + o_CreatureInfo[bankState->defenders.type[i]].name_plural + ": " +
                    getInterval(bankState->defenders.count[i]);
                                     
                // Передаём адрес текстового буфера в качестве аргумента для диалога
                sprintf(o_TextBuffer, "%s", str.c_str());
                c->ecx = (int)o_TextBuffer;
            }
        }

        // Жилища существ
        if ( mapItem->object_type == 0x11 || mapItem->object_type == 0x14 )
        {
            // Получаем состояние жилища существ
            _Dwelling_* dwelling = GetDwelling(mapItem->setup);

            // Если мы владельцы, показываем количество существ
            if ( dwelling && dwelling->owner_ix == o_GameMgr->GetMeID() )
            {
                string str = (char*)c->ecx; // Оригинальное сообщение
                str += "\n";

                for (int i = 0; i < 4; ++i)
                    if ( dwelling->creature_types[i] != ID_NONE )
                        str = str + "\n" + o_CreatureInfo[dwelling->creature_types[i]].name_plural + ": " +
                        getInterval(dwelling->creature_counts[i]);

                // Передаём адрес текстового буфера в качестве аргумента для диалога
                sprintf(o_TextBuffer, "%s", str.c_str());
                c->ecx = (int)o_TextBuffer;
            }
        }

        // Лагерь беженцев
        if ( mapItem->object_type == 0x4E )
        {
            // Передаём адрес текстового буфера в качестве аргумента для диалога
            sprintf(o_TextBuffer, "%s\n\n%s: %s", (char*)c->ecx, o_CreatureInfo[mapItem->os_type].name_plural, getInterval(mapItem->setup).c_str());
            c->ecx = (int)o_TextBuffer;
        }

        // Заброшенная шахта
        if ( mapItem->object_type == 0x35 && mapItem->os_type == 7 )
        {
            // Если есть охрана
            if ( *(char*)(o_GameMgr->Field<int>(0x4E38C) + (mapItem->setup << 6)) < 0 )
            {
                // Если герой выбран
                if ( o_ActivePlayer->selected_hero_id > ID_NONE && o_ActivePlayer->selected_hero_id < 156 )
                {
                    _Hero_* hero = o_GameMgr->GetHero(o_ActivePlayer->selected_hero_id);
                    int heroArmyPower = CALL_1(int, __fastcall, 0x44A950, &hero->army);

                    _Army_* defArmy = (_Army_*)(o_GameMgr->Field<int>(0x4E38C) + (mapItem->setup << 6) + 4);
                    int defArmyPower = CALL_1(int, __fastcall, 0x44A950, defArmy);

                    if ( defArmyPower ) // На всякий (чтобы избежать неожиданного деления на 0)
                    {
                        double k = (double)heroArmyPower / defArmyPower;
                       
                        // Вычисляем координаты входа (можно через PosMixed, но пусть будет так)               
                        int mapSize = o_AdvMgr->map->size;
                        int pos = ((int)mapItem - (int)o_AdvMgr->map->items) / sizeof(_MapItem_);
                        char z = pos >= mapSize * mapSize;
                        char x = pos % mapSize;
                        char y = (pos - z * mapSize * mapSize) / mapSize;
                                           
                        // Получаем количество стеков, на которое разбилась охрана
                        int stackCount = getStacksCount(k, x, y, z);
                       
                        // Выясняем, есть ли улучшенный стек
                        char* upgStr = upgradedStack(k, x, y, z) ? "Yes" : "No";

                        // Передаём адрес текстового буфера в качестве аргумента для диалога
                        sprintf(o_TextBuffer, "%s\n\n%s: %d\n\n%s%d\n\n%s%s", (char*)c->ecx, o_CreatureInfo[defArmy->type[0]].name_plural, defArmy->count[0],
                            "# of stacks: ", getStacksCount(k, x, y, z), "Upgraded stack: ", upgStr);
                        c->ecx = (int)o_TextBuffer;
                    }
                }
            }
        }
    }
   
    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = 1;
            _P = GetPatcher();
            _PI = _P->CreateInstance((char*)"HD.Plugin.ShowGuards");

            // Сообщения по правому клику
            _PI->WriteLoHook(0x415AEE, showGuardsRMB);

            // Сообщения при посещении
            _PI->WriteLoHook(0x4A13E6, showGuards); // стандартных банков
            _PI->WriteLoHook(0x4A1E56, showGuards); // Dragon Utopia
            _PI->WriteLoHook(0x4AC1B9, showGuards); // Crypt, Derelict Ship, Shipwreck
            _PI->WriteLoHook(0x4A18FF, showMonsters); // жилища существ 1-го уровня
            _PI->WriteLoHook(0x4A435C, showRefugeeCamp); // Refugee Camp

            // Сохраняем адрес тайла-входа в объект
            _PI->WriteLoHook(0x413917, saveObjEntranceAddr);

            // Пропускаем сообщения для Склепа, если он посещён
            _PI->WriteLoHook(0x4AC19D, Crypt_SkipMsgIfVisited);
        }
    }

    return TRUE;
}

 
Если честно, лень допиливать :smile14:
Последний раз редактировалось AlexSpl 03 фев 2021, 13:30, всего редактировалось 1 раз.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

Re: Как создать плагин для HD мода

Сообщение Rolex » 02 фев 2021, 22:54

Спасибо за труды. Но, к сожалению, не работает. Падает при при попытке посмотреть охрану по ПКМ. Но по ПКМ, лучше оставить как есть в оригинале общее количество (отображается даже без посещения), а вот разбивку на отряды и грейженный стек отображать только во всплывающем диалоге именно при посещении (Хотите спустится? ДА / НЕТ).

И получается остается еще Пирамида... Тут хорошо, что охрана всегда фиксированная (20 алмазных и 40 золотых). Как я понял, кол-во отрядов алмазных не меняется и всегда 2 по 10 (хотя, может быть, есть случаи когда бывает 1 стек на 20), а вот кол-во отрядов золотых големов меняется от 1 до 5 в зависимости от силы армии и кол-ва отрядов героя.
Rolex писал(а):

И, по ходу, остается еще и Пирамида не сделанная. Там вообще все в комплексе нужно... В диалоге посещения - разбивка на отряды (Алмазные големы: 10-19; Алмазные големы: 10-19; Золотые големы: 20-49), в диалоге по ПКМ после посещения, но отказа от боя общее количество без разбивки (Толпа (20-49) Алмазные големы, и толпа (20-49) Золотые големы из ARRAYTXT), и, получается, убирать диалог при посещении, если Пирамидка уже разграбленная...
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 03 фев 2021, 13:15

Странно. Этот код я тестил. Опять разница в версиях VS? :smile5:

* * *
Нужно глянуть подземелье. Разбивка неправильная.

Вместо этого

Код: Выделить всё
char y = (pos - z * mapSize) / mapSize;

нужно

Код: Выделить всё
char y = (pos - z * mapSize * mapSize) / mapSize;

Вот ещё очень нужный код: как получить x, y, z по _MapItem_*? Выше не самый оптимальный способ. Основан на непрерывности адресного пространства карты.

Попробуйте обернуть используемые структуры #pragma pack/pop. А случай разбивки Пирамиды интересный. Там наверняка свой алгоритм.
Вернуться к началу

offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

Re: Как создать плагин для HD мода

Сообщение RoseKavalier » 03 фев 2021, 13:49

I posted reversal of coordinates for as239 a while back, here they are:
Template version
Mapitem version
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 03 фев 2021, 13:53

Одна и та же идея :smile1: Я думал можно как-то через геройские функции. Проще, конечно, получить PosMixed в коде, но когда это значение неизвестно или лень искать (каждый раз), то, походу, больше никак.

2RoseKavalier: And how do you obtain number of stacks and whether there is an upgraded stack? Calling RandomInt()?
Вернуться к началу

offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

Re: Как создать плагин для HD мода

Сообщение RoseKavalier » 03 фев 2021, 14:07

As far as I know Mapitem is always endpoint from coordinates calculation, never used to go retrieve coordinates... but you never know there are thousands of functions that have not been properly inspected yet!

Split/upgrade:
I have rewritten the code a few weeks ago (not live yet) to store and restore the game seed before performing split/upgrades calculations.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 03 фев 2021, 14:11

And I've done some math with those numbers :smile1:
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

Кто сейчас на конференции

Сейчас этот форум просматривают: Bing [Bot] и гости: 3