![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
![]()
Сообщение
#201
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
хм, я ж не перетираю модификатор, а увеличиваю его
Т.е. не а = 100, а "а = а+100" А в целом идея думаю ясна: есть навык дипломатии. Есть модификатор силы армии. И что бы логику изменения держать в 1м месте, для простоты редактирования и читаемости - геттер модификатора вынес в ф-ю В ней ожидаю все изменения считать. В том числе и артов (пусть в виде доп ф-ии, но не в том суть) Главное что всё в 1м месте |
|
|
![]()
Сообщение
#202
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
В коде посмотрите, как часто функция подсчёта альфы вызывается. Каждый раз, когда она вызывается, Вы делаете это: "а = а+100".
|
|
|
![]()
Сообщение
#203
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
В коде посмотрите, как часто функция подсчёта альфы вызывается. Каждый раз, когда она вызывается, Вы делаете это: "а = а+100". Так всегда одинаковое значение должно быть. Ибо я указываю что модификатор = константным значениям на основании уровня навыка И когда кто либо попросит "а дай мне значение модификатора" оно всегда будет одинаковым. И спрашивать будет в 1м месте. Не прийдётся собирать по разным функциям PS: я кажется понял о чём речь... для разных функций *(int*)(c->edx + 124 + (i << 3) + 4) будет содержать разный контент? По аналогии с дипломатией. Где-то edi, где-то esi, а в 3м месте вообще ebp А я для всех вариантов юзаю edx в расчёте что там будет айди арта В этом проблема? |
|
|
![]()
Сообщение
#204
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Итак, есть код:
getAlpha(); getAlpha(); getAlpha(); Есть хук на getAlpha(), в котором мы пишем: Mod += 10 (например). После выполнения этого кода Mod будет равен 30, но должен быть равен 10. Цитата *(int*)(c->edx + 124 + (i << 3) + 4) будет содержать разный контент? И это тоже. У LoHook'ов разный контекст. В одном c->edx будет возвращать адрес героя, в другом с->edx может хранить горизонтальное разрешение экрана вообще. |
|
|
![]()
Сообщение
#205
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Итак, есть код: getAlpha(); getAlpha(); getAlpha(); Есть хук на getAlpha(), в котором мы пишем: Mod += 10 (например). После выполнения этого кода Mod будет равен 30, но должен быть равен 10. Цитата *(int*)(c->edx + 124 + (i << 3) + 4) будет содержать разный контент? И это тоже. У LoHook'ов разный контекст. В одном c->edx будет возвращать адрес героя, в другом с->edx может хранить горизонтальное разрешение экрана вообще. Вот чесно - не пойму. До добавления артов всё работало корректно. А я по сути только добавил в подсчёт модификатора ещё и арты. Т.е. глобальных изменений не делал Цитата И это тоже. У LoHook'ов разный контекст. В одном c->edx будет возвращать адрес героя, в другом с->edx может хранить горизонтальное разрешение экрана вообще. Вот, а вот это понимаю, это сходится у меня в голове) Но тогда другая проблема. Если делать так: _PI->WriteLoHook(0x44A985, setArmyValueArt); тогда я не смогу корректно увеличить силу армии на 5% от базовой. Потому что буду увеличивать на 5% от уже модифицированной дипломатией Соотв надо разные блоки "*(int*)(c->edx + 124 + (i << 3) + 4) " под каждый тип (превью, нападение, деление на паки) делать? |
|
|
![]()
Сообщение
#206
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Про контекст. Поставьте брейкпоинт по любому из адресов ваших хуков, запустите игру и сделайте так, чтобы он сработал. Содержимое регистров (general registers, FPU registers и т.п.) справа - и есть контекст.
Цитата Но тогда другая проблема. Если делать так: _PI->WriteLoHook(0x44A985, setArmyValueArt); тогда я не смогу корректно увеличить силу армии на 5% от базовой. Потому что буду увеличивать на 5% от уже модифицированной дипломатией Соотв надо разные блоки "*(int*)(c->edx + 124 + (i << 3) + 4) " под каждый тип (превью, нападение, деление на паки) делать? Вы хотите игнорить модификатор Дипломатии, когда есть арт у героя? Т.е. если есть арт, то не учитывать навык Дипломатии вообще? |
|
|
![]()
Сообщение
#207
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Вы хотите игнорить модификатор Дипломатии, когда есть арт у героя? Т.е. если есть арт, то не учитывать навык Дипломатии вообще? Нет. Вот что получится если ставить два хука. Последний (увеличение силы армии от артов) после всех предыдущих просчётов: базовая сила армии 100 едениц Цель. Дипломатия даёт 20%. И арты по 5%. Итого если есть дипломатия и 1н арт, должно получится 25% А если делать разными хуками, то выйдет следующее: силаАрмии = 100; силаАрмии = силаАрмии * 1.2 //бонус от дипломатии (120 получится) силаАрмии = силаАрмии * 1.05 //бонус от артефакта (126 получится) Т.е. я получу 126, вместо 125 ожидаемых |
|
|
![]()
Сообщение
#208
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Понятно. Тогда каждый раз, когда Вы модифицируете силу армии, должна вызываться функция подсчёта "чистой" силы армии, и только потом следует умножать полученное значение на модификатор. Причём старые бонусы должны аккумулироваться. Надо подумать.
* * * Во всех LoHook'ах у нас есть адрес структуры героя. Соответственно, мы можем учесть и уровень Дипломатии и арты. Нужно убирать последний LoHook и дублировать его логику в остальных. * * * Скиньте под спойлер рабочий код, я для каждого LoHook'а напишу адрес "куклы". |
|
|
![]()
Сообщение
#209
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
|
|
|
![]()
Сообщение
#210
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Так и есть, отредактировал пост выше.
|
|
|
![]()
Сообщение
#211
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Вот код с разными хуками
Упс... HookContext* c не поубирал. Но по сути он просто передаётся и не юзается. Ломать ничего не должен |
|
|
![]()
Сообщение
#212
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Вот это
Код _PI->WriteLoHook(0x44A985, setArmyValueArt); и это Код int __stdcall setArmyValueArt(LoHook* h, HookContext* c) { for (int i = 0; i < 19; ++i) { if ( *(int*)(c->edx + 124 + (i << 3) + 4) == 66 ) { c->eax *= 1.05; } } return EXEC_DEFAULT; } нужно убирать. Далее, в функции setArmyValueSplit(), setArmyValuePreview() и setArmyValue() добавить код (на примере первой): Код int __stdcall setArmyValueSplit(LoHook* h, HookContext* c) { float Mod = 0; for (int i = 0; i < 19; ++i) { if ( *(int*)(c->reg + 297 + (i << 3) + 4) == 66 ) Mod += 0.05; } char diplomacyLevel = *(char*)(*(int*)(c->ebp + 8) + 201 + 4); Mod += getArmyValueModifier(diplomacyLevel); c->eax *= 1 + Mod; return EXEC_DEFAULT; } Соответсвенно, здесь поменять модификаторы: Код float getArmyValueModifier(char diplomacyLevel) { float armyModifier[4] = {0.00, 0.10, 0.15, 0.20 /* процент же */}; return ( diplomacyLevel < 4 ? armyModifier[diplomacyLevel] : 0 ); } c->reg заменить на *(int*)(c->ebp + 8), c->esi и c->edi соответственно. * * * Ну всё, кажется, отредактировал ![]() |
|
|
![]()
Сообщение
#213
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
не учитывается модификатор. Я правильно написал?
Код int __stdcall setArmyValueSplit(LoHook* h, HookContext* c) { float Mod = 0; for (int i = 0; i < 19; ++i) { if ( *(int*)(c->ebp + 8 + 297 + (i << 3) + 4) == 66 ) { Mod += 40.05; } } //Mod = 20; char diplomacyLevel = *(char*)(*(int*)(c->ebp + 8) + 201 + 4); float armyModificator = getArmyValueModificator(diplomacyLevel, c); (int)c->eax *= (Mod + armyModificator); return EXEC_DEFAULT; } Вот так никаких изменений. Если расскоментить Mod = 20, тогда делить начинает на 2 пачки, вместо 3х.. Т.е. в условие не заходит |
|
|
![]()
Сообщение
#214
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Не, нужно так:
Код int __stdcall setArmyValueSplit(LoHook* h, HookContext* c) { float Mod = 0; for (int i = 0; i < 19; ++i) { if ( *(int*)(*(int*)(c->ebp + 8) + 297 + (i << 3) + 4) == 66 ) { Mod += 40.05; } } char diplomacyLevel = *(char*)(*(int*)(c->ebp + 8) + 201 + 4); Mod += getArmyValueModifier(diplomacyLevel); (int)c->eax *= 1 + Mod; return EXEC_DEFAULT; } И я отредактировал пост выше (см. функцию getArmyValueModifier()). |
|
|
![]()
Сообщение
#215
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Код int __stdcall setArmyValueSplit(LoHook* h, HookContext* c) { float armyModifier = 0; for (int i = 0; i < 19; ++i) { if ( *(int*)(*(int*)(c->ebp + 8) + 297 + (i << 3) + 4) == 66 ) { armyModifier += 40.05; } } char diplomacyLevel = *(char*)(*(int*)(c->ebp + 8) + 201 + 4); armyModifier += getArmyValueModifier(diplomacyLevel, c); (int)c->eax *= (1 + armyModifier); return EXEC_DEFAULT; } Это работает корректно. Делит на 3 пачки без арта, на 2 с ним А вот превью падает. Код: Код int __stdcall setArmyValuePreview(LoHook* h, HookContext* c)
{ float armyModifier = 0; for (int i = 0; i < 19; ++i) { if ( *(int*)(*(int*)(c->esi + 8) + 297 + (i << 3) + 4) == 66 ) { armyModifier += 40.05; } } int diplomacyLevel = (int)(*(char*)(c->esi + 201 + 4)); armyModifier += getArmyValueModifier(diplomacyLevel, c); (int)c->eax *= (1 + armyModifier); return EXEC_DEFAULT; } |
|
|
![]()
Сообщение
#216
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Превью нужно писать так:
Код int __stdcall setArmyValuePreview(LoHook* h, HookContext* c) { float armyModifier = 0; for (int i = 0; i < 19; ++i) { if ( *(int*)(c->esi + 297 + (i << 3) + 4) == 66 ) { armyModifier += 40.05; } } int diplomacyLevel = (int)(*(char*)(c->esi + 201 + 4)); armyModifier += getArmyValueModifier(diplomacyLevel, c); (int)c->eax *= (1 + armyModifier); return EXEC_DEFAULT; } см. Цитата c->reg заменить на *(int*)(c->ebp + 8), c->esi и c->edi соответственно. Аналогично первый хук поправить на c->edi. Потом здесь - getArmyValueModifier(diplomacyLevel, c); - не нужно передавать контекст, он в этой функции не используется. |
|
|
![]()
Сообщение
#217
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Работает!
![]() Цитата c->reg заменить на *(int*)(c->ebp + 8), c->esi и c->edi соответственно. Я сперва понял что это краткая запись. Мол по такому же принцицу (*(int*)(c->ebp + 8)) и для остальных, меняя только ebp на нужное) Цитата Потом здесь - getArmyValueModifier(diplomacyLevel, c); - не нужно передавать контекст, он в этой функции не используется. угу, в посте выше это писал. Цитата Упс... HookContext* c не поубирал. Но по сути он просто передаётся и не юзается. Ломать ничего не должен Потом уберу) главное функционал По поводу артов, а где айдишники артов посмотреть? т.е. 66 для шеи знаю, а где глянуть остальные. И не только дипломата |
|
|
![]()
Сообщение
#218
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
[Art] 0 Spell Book 1 Spell Scroll 2 The Grail 3 Catapult 4 Ballista 5 Ammo Cart 6 First Aid Tent 7 Centaurs Axe 8 Blackshard of the Dead Knight 9 Greater Gnoll's Flail 10 Ogre's Club of Havoc 11 Sword of Hellfire 12 Titan's Gladius 13 Shield of the Dwarven Lords 14 Shield of the Yawning Dead 15 Buckler of the Gnoll King 16 Targ of the Rampaging Ogre 17 Shield of the Damned 18 Sentinel's Shield 19 Helm of the Alabaster Unicorn 20 Skull Helmet 21 Helm of Chaos 22 Crown of the Supreme Magi 23 Hellstorm Helmet 24 Thunder Helmet 25 Breastplate of Petrified Wood 26 Rib Cage 27 Scales of the Greater Basilisk 28 Tunic of the Cyclops King 29 Breastplate of Brimstone 30 Titan's Cuirass 31 Armor of Wonder 32 Sandals of the Saint 33 Celestial Necklace of Bliss 34 Lion's Shield of Courage 35 Sword of Judgement 36 Helm of Heavenly Enlightenment 37 Quiet Eye of the Dragon 38 Red Dragon Flame Tongue 39 Dragon Scale Shield 40 Dragon Scale Armor 41 Dragonbone Greaves 42 Dragon Wing Tabard 43 Necklace of Dragonteeth 44 Crown of Dragontooth 45 Still Eye of the Dragon 46 Clover of Fortune 47 Cards of Prophecy 48 Ladybird of Luck 49 Badge of Courage 50 Crest of Valor 51 Glyph of Gallantry 52 Speculum 53 Spyglass 54 Amulet of the Undertaker 55 Vampire's Cowl 56 Dead Man's Boots 57 Garniture of Interference 58 Surcoat of Counterpoise 59 Boots of Polarity 60 Bow of Elven Cherrywood 61 Bowstring of the Unicorn's Mane 62 Angel Feather Arrows 63 Bird of Perception 64 Stoic Watchman 65 Emblem of Cognizance 66 Statesman's Medal 67 Diplomat's Ring 68 Ambassador's Sash 69 Ring of the Wayfarer 70 Equestrian's Gloves 71 Necklace of Ocean Guidance 72 Angel Wings 73 Charm of Mana 74 Talisman of Mana 75 Mystic Orb of Mana 76 Collar of Conjuring 77 Ring of Conjuring 78 Cape of Conjuring 79 Orb of the Firmament 80 Orb of Silt 81 Orb of Tempestuous Fire 82 Orb of Driving Rain 83 Recanter's Cloak 84 Spirit of Oppression 85 Hourglass of the Evil Hour 86 Tome of Fire Magic 87 Tome of Air Magic 88 Tome of Water Magic 89 Tome of Earth Magic 90 Boots of Levitation 91 Golden Bow 92 Sphere of Permanence 93 Orb of Vulnerability 94 Ring of Vitality 95 Ring of Life 96 Vial of Lifeblood 97 Necklace of Swiftness 98 Boots of Speed 99 Cape of Velocity 100 Pendant of Dispassion 101 Pendant of Second Sight 102 Pendant of Holiness 103 Pendant of Life 104 Pendant of Death 105 Pendant of Free Will 106 Pendant of Negativity 107 Pendant of Total Recall 108 Pendant of Courage 109 Everflowing Crystal Cloak 110 Ring of Infinite Gems 111 Everpouring Vial of Mercury 112 Inexhaustible Cart of Ore 113 Eversmoking Ring of Sulfur 114 Inexhaustible Cart of Lumber 115 Endless Sack of Gold 116 Endless Bag of Gold 117 Endless Purse of Gold 118 Legs of Legion 119 Loins of Legion 120 Torso of Legion 121 Arms of Legion 122 Head of Legion 123 Sea Captain's Hat 124 Spellbinder's Hat 125 Shackles of War 126 Orb of Inhibition 127 Vial of Dragon Blood 128 Armageddon's Blade 129 Angelic Alliance 130 Cloak of the Undead King 131 Elixir of Life 132 Armor of the Damned 133 Statue of Legion 134 Power of the Dragon Father 135 Titan's Thunder 136 Admiral's Hat 137 Bow of the Sharpshooter 138 Wizard's Well 139 Ring of the Magi 140 Cornucopia |
|
|
![]()
Сообщение
#219
|
|
![]() God Сообщений: 267 Спасибо сказали: 25 раз ![]() |
Не нравится когда много дубликата кода, привожу к более вменяемому виду. не финал, но уже почти:
Код float __stdcall getArmyValueModifier(int baseHeroOffset) { int diplomacyLevel = (int)(*(char*)(baseHeroOffset + 201 + 4)); float armyModifier[4] = {0.00, 0.10, 0.15, 19.00}; float currentModifier = ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModifier[diplomacyLevel] : 1 ); float armyArtModifier = 0; for (int i = 0; i < 19; ++i) { if ( *(int*)(baseHeroOffset + 297 + (i << 3) + 4) == 66 ) { armyArtModifier += 40.05; } } return currentModifier + armyArtModifier; } int __stdcall setArmyValue(LoHook* h, HookContext* c) { int baseHeroOffset = c->edi; float armyModifier = getArmyValueModifier(baseHeroOffset); (int)c->eax *= (1 + armyModifier); return EXEC_DEFAULT; } int __stdcall setArmyValuePreview(LoHook* h, HookContext* c) { int baseHeroOffset = c->esi; float armyModifier = getArmyValueModifier(baseHeroOffset); (int)c->eax *= (1 + armyModifier); return EXEC_DEFAULT; } int __stdcall setArmyValueSplit(LoHook* h, HookContext* c) { int baseHeroOffset = *(int*)(c->ebp + 8); float armyModifier = getArmyValueModifier(baseHeroOffset); (int)c->eax *= (1 + armyModifier); return EXEC_DEFAULT; } Всё работает и почти не дублирую код) |
|
|
![]()
Сообщение
#220
|
|
Immortal Сообщений: 798 Спасибо сказали: 555 раз ![]() |
Только всё-таки diplomacyLevel - это char. Т.е. приведение к int - лишнее.
Код float currentModifier = ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModifier[diplomacyLevel] : 1 ); Почему 1? У нас не модификатор теперь (в понимании множителя), а процент. И currentModifier лучше переименовать в diplomacyBonus. Вообще слово Modifier заменить на Bonus. * * * Если нужна читабельность, то следует прислушаться к совету feanor'а. Создать заголовочный файл (например, hstructs.h): Код struct art { int id; int prop; }; struct hero { char dummy_0[201]; // байты структуры героя с 0-го по 200-й нас не интересуют char secondarySkill[28]; // +201 char dummy_1[72]; // байты структуры героя с 229-го по 300-й тоже не интересуют art dollArt[19]; // +301 // остальные тоже не интересуют }; enum { PATHFINDING, ARCHERY, LOGISTICS, SCOUTING, DIPLOMACY, NAVIGATION, LEADERSHIP, WISDOM, MYSTICISM, LUCK, BALLISTICS, EAGLE_EYE, NECROMANCY, ESTATES, FIRE_MAGIC, AIR_MAGIC, WATER_MAGIC, EARTH_MAGIC, SCHOLAR, TACTICS, ARTILLERY, LEARNING, OFFENSE, ARMORER, INTELLIGENCE, SORCERY, RESISTANCE, FIRST_AID }; Код примерно такой получится: Код #include "hstructs.h"; double getArmyValueModifier(hero* myHero) { double diploBonus[4] = {0.00, 0.10, 0.15, 0.20}; double artBonus = 0.00; for (int i = 0; i < 19; ++i) { if ( myHero->dollArt[i].id == 66 ) artBonus += 0.05; } return 1 + diploBonus[myHero->secondarySkill[DIPLOMACY]] + artBonus; } int __stdcall setArmyValue(LoHook* h, HookContext* c) { c->eax *= getArmyValueModifier((hero*)(c->edi)); return EXEC_DEFAULT; } // и т.п. * * * UPD Поэкспериментировал с артефактами на "кукле" героя. Действительно, ID артефакта идёт первым (почему-то казалось, что вторым). Соответственно, исправил стуктуры art и hero в коде выше. Старый код со смещением артов 297 + (i << 3) + 4 будет работать всё равно (из-за +4), но правильно записывать смещение так: 301 + (i << 3). Прошу прощения. Таким образом, смещение "куклы" в структуре feanor'а указано верно и тупил я. |
|
|
![]() ![]() |
Текстовая версия | Сейчас: 3 October 2025 - 21:31 |
Copyright by Алексей Крючков
![]() Programming by Degtyarev Dmitry |
|