IPB

Здравствуйте, гость ( Вход | Регистрация )

29 страниц V  « < 6 7 8 9 10 > »   
Reply to this topicStart new topic
> Мод на ХотА
DedMorozzz
сообщение 18 Dec 2016, 20:13 (Сообщение отредактировал DedMorozzz - 18 Dec 2016, 20:16)
Сообщение #141

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 18:41) *
Только, если я правильно понимаю, контекст локальный, поэтому это: *(char*)(c->esi + 201 + 4) не будет возвращать уровень Дипломатии.


Угу, стоит обернуть в проверку дипломатии, и сразу падает игра. При этом просто (*(char*)(c->esi + 201 + 4) >0 ) { //тут пусто} не падает smile.gif
Каким образом в данном контексте дипломатию получить?
Метода аля "гетКаррентХиро" не вижу

PS: хотя странно. Для текущего же героя беру силу армии. Вот для текущего героя и хочу получить дипломатию. Не понятно чего не будет её возвращать..
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 20:34 (Сообщение отредактировал AlexSpl - 18 Dec 2016, 20:38)
Сообщение #142

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




В нашем случае:

Код
*(char*)(c->edi + 205)


Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
     char DiploLevel = *(char*)(c->edi + 205);
    
     switch ( DiploLevel ) {
          case 1: (int)c->eax = (int)c->eax * 1.05f;
          case 2: (int)c->eax = (int)c->eax * 1.10f;
          case 3: (int)c->eax = (int)c->eax * 1.15f;
     }
        
     return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);


Или так:

Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
     char DiploLevel = *(char*)(c->edi + 205);
     float Mod;

     switch ( DiploLevel ) {
          case 1: Mod = 1.05;
          case 2: Mod = 1.10;
          case 3: Mod = 1.15;
     }
    
     (int)c->eax = (int)c->eax * Mod;    
        
     return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 20:37 (Сообщение отредактировал DedMorozzz - 18 Dec 2016, 20:38)
Сообщение #143

God
Сообщений: 267
Спасибо сказали: 25 раз




Получилось! Вот код:
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
    int diplomatyLevel = (int)(*(char*)(c->edi + 205));
    if (diplomatyLevel > 0) {
        if (diplomatyLevel == 1) {
            (int)c->eax = (int)c->eax * 1.1;
        }

        if (diplomatyLevel == 2) {
            (int)c->eax = (int)c->eax * 1.15;
        }

        if (diplomatyLevel == 3) {
            (int)c->eax = (int)c->eax * 1.2;
        }
    }

    return EXEC_DEFAULT;
}


Почему тут edi юзать? И чем от esi отличается?

PS: Ага, вижу обновлёный пост со свичем... покрасивее будет. И решил 10-15-20 сделать smile.gif
и DiploLevel это же инт. Я у себя в коде интом обозвал его и работает
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 20:43 (Сообщение отредактировал AlexSpl - 18 Dec 2016, 20:48)
Сообщение #144

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




А так работает?

Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
    char DiploLevel = *(char*)(c->edi + 205);
    float Mod;

    switch ( DiploLevel ) {
        case 1: Mod = 1.05;
        case 2: Mod = 1.10;
        case 3: Mod = 1.15;
    }
    
    (int)c->eax *= Mod;    
        
    return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);


Цитата
Почему тут edi юзать? И чем от esi отличается?

Потому что в данном контексте указатель на стуктуру героя хранится в регистре edi.
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 20:52 (Сообщение отредактировал DedMorozzz - 18 Dec 2016, 20:52)
Сообщение #145

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 19:43) *
А так работает?

Цитата
Почему тут edi юзать? И чем от esi отличается?

Потому что в данном контексте указатель на стуктуру героя хранится в регистре edi.


Да, так работает тоже. Финальный вариант кода:
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
    
    int diplomatyLevel = (int)(*(char*)(c->edi + 201 + 4));
    if (diplomatyLevel > 0) {
        float armyModificator = 1;

        switch (diplomatyLevel) {
          case 1: armyModificator = 1.1;
          case 2: armyModificator = 1.15;
          case 3: armyModificator = 1.2;
        }
        
        (int)c->eax *= armyModificator;
    }

    return EXEC_DEFAULT;
}


Ибо в коде выше (не проверял, без дипломатии) но по логике если дипломатии нету, то модификатор будет пустым. И на пустоту умножу текущую силу армии, не уверен что это то что надо smile.gif

А насчёт edi/esi как понять когда что нужно? Пока что логика не ясна
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 20:57 (Сообщение отредактировал AlexSpl - 18 Dec 2016, 21:08)
Сообщение #146

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Цитата
Ибо в коде выше (не проверял, без дипломатии) но по логике если дипломатии нету, то модификатор будет пустым. И на пустоту умножу текущую силу армии, не уверен что это то что надо

В свитче default пропиши.

Цитата
А насчёт edi/esi как понять когда что нужно? Пока что логика не ясна

esi и edi - это регистры процессора (просто контейнеры). Адрес героя мог бы и в ecx храниться. Всё зависит от контекста. Конкретно в каждом случае нужно код смотреть.

Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
    char DiploLevel = *(char*)(c->edi + 205);
    float Mod;

    switch ( DiploLevel ) {
        case 1: {
            Mod = 1.05;
            break;
        }
        
        case 2: {
            Mod = 1.10;
            break;
        }
        
        case 3: {
            Mod = 1.15;
            break;
        }
        
        default: Mod = 1.00;
    }
    
    (int)c->eax *= Mod;    
        
    return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4A7441, (void*)setArmyValue);
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 21:03
Сообщение #147

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 19:57) *
В свитче default пропиши.

Не нужно уже smile.gif
Я заходить буду в блок пересчёта силы армии, только при наличии дипломатии.
Но для понимания "дефолтного" значения при объявлении переменой присвоил ей еденицу.
В принципе и комментом можно было это сделать
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 21:30 (Сообщение отредактировал DedMorozzz - 18 Dec 2016, 21:31)
Сообщение #148

God
Сообщений: 267
Спасибо сказали: 25 раз




Предпросмотр не завёлся
Нашел метод предпросмотра (скорее всего нашел smile.gif )
_PI->WriteLoHook(0x4171DB, setArmyValue); - тут в Dlg_MonsterRMHint вызывается sub_426750
Пробовал и на адреса ниже, по аналогии с 0x4A7441 ибо меняли 0x4A7441, а метод вызывается на 2 строчки выше (004A7439)

Итого пробовал вот эти адреса ещё:
_PI->WriteLoHook(0x4171E0, setArmyValue);
_PI->WriteLoHook(0x4171E6, setArmyValue);

Везде ошибка, при ПКМ на монстре. При этом нападаю если - всё работает штатно

PS: и да, брейки в код добавил
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 21:35
Сообщение #149

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Цитата
_PI->WriteLoHook(0x4171DB, setArmyValue);

Ставь LoHook на следующую инструкцию после call: 4171E0h
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 21:39
Сообщение #150

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 20:35) *
Цитата
_PI->WriteLoHook(0x4171DB, setArmyValue);

Ставь LoHook на следующую инструкцию после call: 4171E0h


Следующая строчка это "4171E6"
Для неё тоже пробовал, в посте выше есть этот адрес
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 22:02 (Сообщение отредактировал AlexSpl - 18 Dec 2016, 22:03)
Сообщение #151

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Предпросмотр который? Visions?

Замени edi на esi.

Код
char DiploLevel = *(char*)(c->esi + 205);


Хук на 4171E0h или 4171E6h - не важно.


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 22:04 (Сообщение отредактировал DedMorozzz - 18 Dec 2016, 22:04)
Сообщение #152

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 21:00) *
Предпросмотр который? Visions?

Замени edi на esi.

Да! Так работает. Вообще не ясна логика когда что юзать... кроме как наугад менять

И как вот эту штуку сделать рабочей
Цитата
Код
_PI->WriteDword((0x417236 + 1), 3);    // при ПКМ


Ибо показывает что присоеденятся при предпросмотре (да-да, Vision), а по факту убегают/нападают
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 22:26 (Сообщение отредактировал AlexSpl - 18 Dec 2016, 22:34)
Сообщение #153

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Цитата
Да! Так работает. Вообще не ясна логика когда что юзать... кроме как наугад менять

Ставь брейкпоинт на 4171E6h и смотри в каком регистре хранится указатель на героя. Т.е. G[o] -> 4171E6, F2, кастуем Visions, ПКМ, срабатывает брейкпоит, анализируем код.

Цитата
И как вот эту штуку сделать рабочей

Просто убери.

Там другой патч нужен.

Попробуй так:

Код
_PI->WriteHexPatch(0x417234, "EB");  // проходим мимо бесплатного присоединения
_PI->WriteHexPatch(0x417246, "EB");  // проходим мимо платного присоединения


HiHook на sub_4170B0.


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 22:37 (Сообщение отредактировал DedMorozzz - 18 Dec 2016, 22:42)
Сообщение #154

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 21:26) *
Цитата
Да! Так работает. Вообще не ясна логика когда что юзать... кроме как наугад менять

Ставь брейкпоинт на 4171E6h и смотри в каком регистре хранится указатель на героя. Т.е. G[o] -> 4171E6, F2, кастуем Visions, ПКМ, срабатывает брейкпоит, анализируем код.

https://sc-cdn.scaleengine.net/i/fbe739dbe6...02d39ddd287.png
Прошелся по коду. Там этих edi/esi уйма. И все подряд идут)

Цитата(AlexSpl @ 18 Dec 2016, 21:26) *
Попробуй так:

Код
_PI->WriteHexPatch(0x417234, "EB");  // проходим мимо бесплатного присоединения
_PI->WriteHexPatch(0x417246, "EB");  // проходим мимо платного присоединения

Работает smile.gif Круто

Кстати новый код что бы не дублировать логику для дипломатии, для нападения и для Вижина (20 для теста юзаю):


Код
float __stdcall getArmyValueModificator(int diplomatyLevel)
{

    float armyModificator = 1;

    if (diplomatyLevel > 0) {
        switch (diplomatyLevel) {
            case 1: {
                armyModificator = 1.1;
                break;
            }
            
            case 2: {
                armyModificator = 1.15;
                break;
            }
            
            case 3: {
                armyModificator = 20;
                break;
            }
        }
    }

    return armyModificator;

}

int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
    int diplomatyLevel = (int)(*(char*)(c->edi + 201 + 4));
    float armyModificator = getArmyValueModificator(diplomatyLevel);
    (int)c->eax *= armyModificator;

    return EXEC_DEFAULT;
}


int __stdcall setArmyValuePreview(LoHook* h, HookContext* c)
{
    int diplomatyLevel = (int)(*(char*)(c->esi + 201 + 4));
    float armyModificator = getArmyValueModificator(diplomatyLevel);
    (int)c->eax *= armyModificator;

    return EXEC_DEFAULT;
}


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 22:43 (Сообщение отредактировал AlexSpl - 18 Dec 2016, 23:24)
Сообщение #155

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Только в этом:

Код
if (diplomatyLevel > 0)


нет смысла, т.к. дефолтный float armyModificator = 1; уже прописан. Я рекомендую всё-таки прописать его в default.

P.S. Разве не стоит цель оптимизировать. Но в этом случае вообще от свитча уходить нужно smile.gif Обычный array c проверкой границ был бы быстрее и компактнее (в коде).

Код
float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
return ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModificator[diplomacyLevel] : ERROR_CODE );
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 23:17
Сообщение #156

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 21:43) *
Только в этом:

Код
if (diplomatyLevel > 0)


нет смысла, т.к. дефолтный float armyModificator = 1; уже прописан. Я рекомендую всё-таки прописать его в default.

хм. Не соглашусь.. Без этой проверки свич/кейс будет выполняться всегда. Даже когда дипломатия отсутствует

Цитата(AlexSpl @ 18 Dec 2016, 21:43) *
P.S. Разве не стоит цель оптимизировать. Но в этом случае вообще от свитча уходить нужно smile.gif Обычный array c проверкой границ был бы быстрее и компактнее (в коде).

Код
float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
return armyModificator[diplomacyLevel];

Тоже верно. Но если потребуется чуть расширить, кроме как модификатор изменить, тогда массив не пойдёт уже)
Но на кейсы можно будет переделать, когда потребуется. Сейчас действительно через массив сделаю

И ещё вопрос по теме дипломатии:
Где проверка можно ли сдаться стоит? Хочу сделать при наличии навыка дипломатии - возможность сдаваться мобам. С ценой 30-20-10%. В зависимости от левела навыка...
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 23:24 (Сообщение отредактировал AlexSpl - 18 Dec 2016, 23:26)
Сообщение #157

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Можно так:

Код
float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
return ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModificator[diplomacyLevel] : ERROR_CODE );


Хотя у нас char, тогда ещё проще:

Код
float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
return ( diplomacyLevel < 4 ? armyModificator[diplomacyLevel] : ERROR_CODE );
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 18 Dec 2016, 23:32 (Сообщение отредактировал DedMorozzz - 19 Dec 2016, 00:43)
Сообщение #158

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 22:24) *
Можно так:

Код
float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
return ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModificator[diplomacyLevel] : ERROR_CODE );


Хотя у нас char, тогда ещё проще:

Код
float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
return ( diplomacyLevel < 4 ? armyModificator[diplomacyLevel] : ERROR_CODE );


Да, так вообще кратко вышло) хз есть ли эксепшины тут, но на эррор код - ругается. Вставил еденицу
И кстати да, Diplomacy верно, а не Diplomaty, спасибо, позаменял в коде)

И я ещё забыл разбивку по пакам сделать. Пока что при "равной" силе, с модификатором х20, когда нападаешь делит на 7 пачек.
Думаю дето в этой функе это логика sub_004A68D0. Поковыряю, отпишусь, если найду
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 18 Dec 2016, 23:38 (Сообщение отредактировал AlexSpl - 18 Dec 2016, 23:42)
Сообщение #159

Immortal
Сообщений: 798
Спасибо сказали: 555 раз




Цитата
И кстати да, Diplomacy верно, а не Diplomaty, спасибо, позаменял в коде)

Это я инстинктивно исправил. Но если идти дальше, то правильно armyModifier smile.gif

Цитата
И я ещё забыл разбивку по пакам сделать. Пока что при "равной" силе, с модификатором х20, когда нападаешь делит на 7 пачек.

Тот же LoHook, но на "альфу". Когда игра разбивает нейтралов на стеки, роляет только "альфа".


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 19 Dec 2016, 22:30
Сообщение #160

God
Сообщений: 267
Спасибо сказали: 25 раз




Цитата(AlexSpl @ 18 Dec 2016, 22:38) *
Цитата
И я ещё забыл разбивку по пакам сделать. Пока что при "равной" силе, с модификатором х20, когда нападаешь делит на 7 пачек.

Тот же LoHook, но на "альфу". Когда игра разбивает нейтралов на стеки, роляет только "альфа".


0x4AC35E
0x4AC361
0x427662
0x427664
0x4A6B00
0x4AC34F

Для каждого из этих адрессов, пробовал вызывать LoHook. Как для "setArmyValue" так и для "setArmyValuePreview"
Т.е.
_PI->WriteLoHook(0x4AC35E, setArmyValue);
не работает, пробую это:
_PI->WriteLoHook(0x4AC35E, setArmyValuePreview);

В общем не завелось не для какого адресса. Всегда 7 пачек.
Какой адрес правильный?
Go to the top of the pageAdd Nick
 
+Quote Post

29 страниц V  « < 6 7 8 9 10 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 3 October 2025 - 17:45
Copyright by Алексей Крючков
Strategy Gamez by GrayMage
Programming by Degtyarev Dmitry
  Яндекс.Метрика