IPB

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

29 страниц V  « < 7 8 9 10 11 > »   
Reply to this topicStart new topic
> Мод на ХотА
AlexSpl
сообщение 19 Dec 2016, 23:43 (Сообщение отредактировал AlexSpl - 19 Dec 2016, 23:52)
Сообщение #161

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




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

Код
int __stdcall setArmyValueSplit(LoHook* h, HookContext* c)
{
    char diplomacyLevel = *(char*)(c->ebx + 56 + 4);
    ...
    return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4AC35E, (void*)setArmyValueSplit);


c->ebx в данном контексте указатель на армию героя (+145). Навыки начинаются с +201. Поэтому уровень Дипломатии - это c->ebx + (201 - 145) + 4.

Ещё вариант: char diplomacyLevel = *(char*)(*(int*)(с->ebp + 8) + 201 + 4), но он более громоздкий.

Теория по разбиению на стеки здесь: http://heroescommunity.com/viewthread.php3...D=1266094#focus


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

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




Цитата(AlexSpl @ 19 Dec 2016, 22:43) *
Попробуйте так:

Код
int __stdcall setArmyValueSplit(LoHook* h, HookContext* c)
{
    char diplomacyLevel = *(char*)(c->ebx + 56 + 4);
    ...
    return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x4AC35E, (void*)setArmyValueSplit);


c->ebx в данном контексте указатель на армию героя (+145). Навыки начинаются с +201. Поэтому уровень Дипломатии - это c->ebx + (201 - 145) + 4.

Ещё вариант: char diplomacyLevel = *(char*)(*(int*)(с->ebp + 8) + 201 + 4), но он более громоздкий.

Теория по разбиению на стеки здесь: http://heroescommunity.com/viewthread.php3...D=1266094#focus

вылетает. прогнал по всем адресам(которые выше кидал) - или вылетает или не работает

PS: а вот это работает!
Код
int diplomacyLevel = (int)(*(char*)(c->ebx + 56 + 4));

Код
_PI->WriteLoHook(0x4AC35E, setArmyValueSplit);
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 20 Dec 2016, 01:19
Сообщение #163

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




Оба варианта?
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 20 Dec 2016, 01:21
Сообщение #164

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




Цитата(AlexSpl @ 20 Dec 2016, 00:19) *
Оба варианта?

отредачил
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 20 Dec 2016, 01:27
Сообщение #165

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




Цитата
int diplomacyLevel = (int)(*(char*)(c->ebx + 56 + 4));

Не нужет тут int. Просто char diplomacyLevel = *(char*)(c->ebx + 56 + 4);

Т.е. не работает вот это: char diplomacyLevel = *(char*)(*(int*)(с->ebp + 8) + 201 + 4)?

Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 20 Dec 2016, 01:32
Сообщение #166

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




Цитата(AlexSpl @ 20 Dec 2016, 00:27) *
Т.е. не работает вот это: char diplomacyLevel = *(char*)(*(int*)(с->ebp + 8) + 201 + 4)?

тут такая ошибка:

1>.\dllmain.cpp(268) : error C2065: 'с' : undeclared identifier
1>.\dllmain.cpp(268) : error C2227: left of '->ebp' must point to class/struct/union/generic type
1> type is ''unknown-type''
1>.\dllmain.cpp(270) : warning C4244: '*=' : conversion from 'float' to 'int', possible loss of data


Цитата(AlexSpl @ 20 Dec 2016, 00:27) *
Цитата
int diplomacyLevel = (int)(*(char*)(c->ebx + 56 + 4));

Не нужет тут int. Просто char diplomacyLevel = *(char*)(c->ebx + 56 + 4);

Да, так тоже работает. А чего инт не нужен, я так понимаю что уровень навыка это не символ, а число, т.е. инт
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 20 Dec 2016, 01:54 (Сообщение отредактировал AlexSpl - 20 Dec 2016, 03:17)
Сообщение #167

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




Потому что
Цитата
_byte_ second_skill[28]; // +201

char - это _byte_

char - это не символ. Просто символы ASCII умещаются в 1 байт. И решили так назвать.

В ассемблере всё проще, нет signed и unsigned, char и прочих "высокоуровневых" типов, есть
db - байт, dw - слово (два байта в архитектуре x86), dd - двойное слово (четыре байта) и т.д. Даже float - тот же dd. Типы придуманы для контроля типов smile.gif Чтобы уменьшить вероятность ошибки при написании кода человеком.

* * *

Цитата
1>.\dllmain.cpp(268) : error C2065: 'с' : undeclared identifier
1>.\dllmain.cpp(268) : error C2227: left of '->ebp' must point to class/struct/union/generic type
1> type is ''unknown-type''
1>.\dllmain.cpp(270) : warning C4244: '*=' : conversion from 'float' to 'int', possible loss of data

Warning понятно откуда. Можете использовать floor() здесь:
Код
(int)c->eax *= Mod;

Код
(int)c->eax = floor((int)c->eax * Mod);

Но не уверен, что floor() быстрее.

Но остальное интересно.
Цитата
1>.\dllmain.cpp(268) : error C2065: 'с' : undeclared identifier

c точно в английской раскладке набрали?

Если да, попробуйте просто присвоить:

Код
int Value = (int)c->ebp;

будет работать?



Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 20 Dec 2016, 21:08
Сообщение #168

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




Цитата(AlexSpl @ 20 Dec 2016, 00:54) *
Потому что
Цитата
_byte_ second_skill[28]; // +201

char - это _byte_

char - это не символ. Просто символы ASCII умещаются в 1 байт. И решили так назвать.

В ассемблере всё проще, нет signed и unsigned, char и прочих "высокоуровневых" типов, есть
db - байт, dw - слово (два байта в архитектуре x86), dd - двойное слово (четыре байта) и т.д. Даже float - тот же dd. Типы придуманы для контроля типов smile.gif Чтобы уменьшить вероятность ошибки при написании кода человеком.

хм... я ж С++ использую, он то высокоуровневый

Цитата(AlexSpl @ 20 Dec 2016, 00:54) *
Но остальное интересно.
Цитата
1>.\dllmain.cpp(268) : error C2065: 'с' : undeclared identifier

c точно в английской раскладке набрали?


Вот из этого поста http://forum.df2.ru/index.php?s=&showt...st&p=734319
взял код:

И там действительно кириллица затесалась. Заменив - завелось

Цитата(AlexSpl @ 20 Dec 2016, 00:54) *

Инт8 это кол-во байт, я правильно понимаю?
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 20 Dec 2016, 21:19
Сообщение #169

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




Цитата
И там действительно кириллица затесалась. Заменив - завелось

Тогда я виноват smile.gif

Цитата
Инт8 это кол-во байт, я правильно понимаю?

Кол-во бит: 8, 16, 32 или 64. Это просто синонимы стандартных типов.

Цитата
The types __int8, __int16, and __int32 are synonyms for the ANSI types that have the same size, and are useful for writing portable code that behaves identically across multiple platforms.
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 20 Dec 2016, 21:26
Сообщение #170

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




Такой вопрос:
я хочу задейстовать арты дипломатии. Что бы не были бесполезным мусором. Что бы арты так же давали бонус к силе армии. Нашел такой код (в подсчёте навыка дипломатии)
Код
.text:004E4857 loc_004E4857:                                              ; CODE XREF: GetDiplomacyPower+73j
.text:004E4857                     cmp     dword ptr [eax], 66            ; Statesman's Medal
.text:004E485A                     jz      short loc_004E488D             ; Jump if Zero (ZF=1)
.text:004E485C                     inc     ecx                            ; Increment by 1
.text:004E485D                     add     eax, 8                         ; Add
.text:004E4860                     cmp     ecx, 13h                       ; Compare Two Operands
.text:004E4863                     jl      short loc_004E4857             ; Jump if Less (SF!=OF)
.text:004E4865                     mov     eax, ArtSettingsPo
.text:004E486A                     mov     eax, [eax+858h]
.text:004E4870                     cmp     eax, 0FFFFFFFFh                ; Compare Two Operands
.text:004E4873                     jz      short loc_004E4899             ; Jump if Zero (ZF=1)
.text:004E4875                     mov     edx, ComboArtSetUpPo
.text:004E487B                     lea     ecx, [eax+eax*2]               ; Load Effective Address
.text:004E487E                     mov     eax, [edx+ecx*8]
.text:004E4881                     mov     ecx, edi
.text:004E4883                     push    eax
.text:004E4884                     call    HeroHasArt                     ; Call Procedure
.text:004E4889                     test    al, al                         ; Logical Compare
.text:004E488B                     jz      short loc_004E4899             ; Jump if Zero (ZF=1)


Как я понимаю это медаль дипломата. Как его задейстовать в логике? Что бы давал +5% к силе армии
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 20 Dec 2016, 21:33 (Сообщение отредактировал AlexSpl - 20 Dec 2016, 21:42)
Сообщение #171

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




Итак, у нас есть функция подсчёта "альфы", которая в цикле проходит по всем слотам армии героя. Единственное правильное решение - добавить в эту функцию код, который бы проходил также и по всем артам, висящим на "кукле" героя, и модифицировал бы "альфу" при наличии того или иного арта.

Так как адрес героя внутри функции известен, то и адрес массива артов - тоже. Так что не должно быть сложно реализовать. Можно обойтись LoHook'ом.
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 20 Dec 2016, 21:41
Сообщение #172

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




Алгорит сам ясен, в нём сложностей нету. Как я себе это вижу:
У нас есть метод (HeroHasArt), судя по всему котороый проверяет наличие арта у героя и возвращает 0/1 скорее всего, сомневаюсь что булеан
Соотв в своей ф-и возврата модификатора, необходимо добавить условие арта. Который ещё дополнительно будет усиливаться надетыми предметами (естественно только указаными)

Что тут для меня не ясно:
1. как передать идентификатор на арт который надо проверить в ф-ю
2. как получить ответ от ф-ии

Остальное - просто smile.gif
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 20 Dec 2016, 21:50 (Сообщение отредактировал AlexSpl - 20 Dec 2016, 22:01)
Сообщение #173

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




Тут нет смысла вызывать эту функцию. Просто пройтись по _Artifact_ doll_art[19]; // +301

LoHook на 44A985h. Дальше простой цикл for (;;). Тут необходимо учесть структуру _Artifact_. Если я правильно помню - это пары dd, второе число (int) в паре - ID арта. Первое - без понятия, возможно, для "замков". c->eax - сила армии.

if ( *(int*)(c->reg + 301 + i) == DIPLOMACY_ART_ID ) c->eax *= diplomacyArtPowerMod[DIPLOMACY_ART_ID];

где i проходит по всем артам на "кукле".


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 20 Dec 2016, 22:34 (Сообщение отредактировал AlexSpl - 21 Dec 2016, 17:26)
Сообщение #174

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




c->edx в данном контексте - указатель на кол-во существ в первом слоте, т.е. адрес "куклы" будет такой: с->edx + 301 - 145 - 7*4 = с->edx + 128.

Поэтому для медали (ID = 66) следующий код должен работать (Mod - модификатор):

Код
for (int i = 0; i < 19; ++i) {
    if ( *(int*)(c->edx + 128 + (i << 3) + 4) == 66 ) c->eax *= Mod;
}

(i << 3) + 4 = i * 8 + 4 - оффсет ID арта.

UPD: Поправил адрес "куклы" и приоритет операций.


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
feanor
сообщение 21 Dec 2016, 19:39
Сообщение #175

laughed as one fey
Сообщений: 12 167
Спасибо сказали: 20603 раза




Цитата
Первое - без понятия, возможно, для "замков".
Параметр конкретного арта, используется для свитков.

Зачем вы используете эти страшные конструкции со смещениями, если у вас есть описание структуры данных?
((_Hero_*)c->edx)->arts[i].id или как-то так примерно.


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 21 Dec 2016, 19:50
Сообщение #176

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




Цитата
((_Hero_*)c->edx)->arts[i].id или как-то так примерно.

У меня есть только структура. Без описания типов конкретных полей (_Army_, _Artifact_, _HStringF_ и т.п.).
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 21 Dec 2016, 23:08
Сообщение #177

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




Цитата(AlexSpl @ 20 Dec 2016, 21:34) *
c->edx в данном контексте - указатель на кол-во существ в первом слоте, т.е. адрес "куклы" будет такой: с->edx + 301 - 145 - 7*4 = с->edx + 128.

Поэтому для медали (ID = 66) следующий код должен работать (Mod - модификатор):

Код
for (int i = 0; i < 19; ++i) {
    if ( *(int*)(c->edx + 128 + (i << 3) + 4) == 66 ) c->eax *= Mod;
}

(i << 3) + 4 = i * 8 + 4 - оффсет ID арта.

UPD: Поправил адрес "куклы" и приоритет операций.

Как из адресса указателя на кол-во существ в 1м слоте получилась конструкция "301-145-7*4"? Вообще не понятно ):
И где глянуть айдишники артов?

Ну и не работает этот код:
Код
if ( *(int*)(c->edx + 128 + (i << 3) + 4) == 66 )

и этот тоже, соответственно:
Код
if ( *(int*)(c->edx + 128 + i * 8 + 4) == 66 )

Вылетает при нападении. И не важно есть арты или нету
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 21 Dec 2016, 23:10
Сообщение #178

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




А так?
Код
if ( *(int*)(c->edx + 128 + (i << 3) + 4) == 66 ) (int)c->eax *= Mod;
Go to the top of the pageAdd Nick
 
+Quote Post
DedMorozzz
сообщение 21 Dec 2016, 23:15 (Сообщение отредактировал DedMorozzz - 21 Dec 2016, 23:15)
Сообщение #179

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




Цитата(AlexSpl @ 21 Dec 2016, 22:10) *
А так?
Код
if ( *(int*)(c->edx + 128 + (i << 3) + 4) == 66 ) (int)c->eax *= Mod;

Так это то же самое.
Вот полный код:
Код
float __stdcall getArmyValueModificator(int diplomacyLevel, HookContext* c)
{
    float armyModificator[4] = {1.00, 1.10, 1.15, 20.00};
    float currentModifier = ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModificator[diplomacyLevel] : 1 );

    for (int i = 0; i < 19; ++i) {
        if ( *(int*)(c->edx + 128 + (i << 3) + 4) == 66 ) {
            //currentModifier = currentModifier + 20;
            currentModifier = 30;
        }
    }
    
    return currentModifier;
}

т.е. при наличии арта делает модификатор = 30
Go to the top of the pageAdd Nick
 
+Quote Post
AlexSpl
сообщение 21 Dec 2016, 23:19
Сообщение #180

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




Закомментируйте вот это:

Код
/* for (int i = 0; i < 19; ++i) {
        if ( *(int*)(c->edx + 128 + (i << 3) + 4) == 66 ) {
            //currentModifier = currentModifier + 20;
            currentModifier = 30;
        }
    } */


И возвратите 30: return 30; Работает?
Go to the top of the pageAdd Nick
 
+Quote Post

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

 



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