Джебус мод, баланс мод для шаблона джебус |
Здравствуйте, гость ( Вход | Регистрация )
Джебус мод, баланс мод для шаблона джебус |
05 Feb 2017, 00:04
(Сообщение отредактировал hippocamus - 05 Feb 2017, 23:52)
Сообщение
#1
|
|
God Сообщений: 267 Спасибо сказали: 25 раз |
Джебус баланс мод
Мод создавался со следующей идеей. Сделать игру более разнообразной. Что бы игра подстраивалась под выпадающие навыки и от них строить свою стратегию А не как в СОДе/ХотЕ - многие навыки откровенно ужасные, которые не нужны никому и никогда. Т.е. основная цель - убрать бесполезные навыки или субъективно слабые усилить То же самое касается для замков. Их и так было не слишком много конкурентных, а с нефром андедов и конфлюкса - стало ещё меньше, речь именно о джебусе После этого возникла идея подправить баланс под текущие реалии. При этом не отходить от классической идеи Т.е. всякие воскрешения палаткой, 3й апгрейд для 7х юнитов, командиры и прочее даже не рассматриваются Мод тестировался исключительно на ХотЕ, хотя изменения проводились общего кода с СОДом. И на хот сите, игра по сети не тестировалась Строения в замках: - Люди. Для ангелов необходим ГМ2, для архов ГМ3 - Оплот. ГМ2 для драконов требовало, теперь ГМ1 - Инферно. Дьяволы не требуют пит лордов не улучшеных (изверги вроде) для постройки - Темница. ГМ2 для драконов требовало, теперь ГМ1 - Варвары. Бегемоты требуют теперь циклопов. Циклопы - птиц, вместо огров Специализация: Специализацию по след. навыкам сделал по 2% за левел вместо 5% - Логистика - Нападение - Защита - Некромантия Навыки: - Мистицизм. 1-7-14-21ед - Некромантия. 0-15-30-45% - Сопротивление. 0-15-25-35% - Колдовство. 0-10-20-30% - Обучение. 0-15-30-45% "Базовый" процент в 0-10-20-30 Джебус это только Исра и Ведомина. Остальные герои вне конкуренции... Итого Исра на 20м левеле имел 70% некромантии без артов С новым процентов (15-30-45) на 20м уровне будет 73% некромантии. Другими словами процент сделал более сильным в начале но супер буста не получится При этом такой герой как Тант теперь тоже более чем играбелен. Может в дальнейшем и добавлю других Арты некромантии: 5%/10%/15% (шея, плечи, сапоги) (Т) - значит изменения в текстовике. Только плагина будет недостаточно, необходимо подключить доп *.lod файл Магия: - Замедление. Теперь округляет в большую сторону. Т.е. у юнита со скоростью 5, после замедления будет скорость не 2, а 3. И манакост +2. Т.е. 8, но только для эксперта (манакост в текстовике) - Молитва. Даёт 6 атаки/защита, 4 скорости и благо. Манакост уменшил до 8 на эксперте (манакост в текстовике) - Взрыв теперь магия огня (Т) - Огенный шар, базовый урон вместо 15/15/30/60 стал 20/30/50/80. СП вместо 10 сделал 20 (Т) - Инферно, базовый урон вместо 20/20/40/80 стал 30/50/80/120. СП вместо 10 сделал 20 (Т) Юниты в городах: Инферно: - инфриты (и улучшенные) на 100 голды дешевле (Т) - дьяволы (и улучшенные) дешевле на 500 голды (Т) - дьяволы -3к на постройку (12 теперь) (Т) Темница: - красные драконы (постройка) стоят 10к и 10 серы (Т) Болото: - Гидры 10 серы (Т) Навыки: 1. Для всех навыков, которые работаю в тою но не действуют в бою в банках существ (далее банки), добавлен альтернативный бонус 2. Все навыки остались как есть, только добавлено новое, если в опиасании прямо не сказано обратного - поиск пути добавляет +1/2/3 к скорости юнита для пересчёта хода на начало дня Т.е. при улучшеном поиске пути герой с вампиром-лордом (скорость 9) будет бегать так же как если бы начал ход с ангелом - тактика во время боя в банке, на 1й ход даётся +1/2/3 скорости всем юнитам. Соотв. во 2м раунд бонус уже не действует - артиллерия во время боя в банке и при наличии балисты/пушки в инвентаре даёте +1/2/3 атаки (само собой при наличии навыка) - первая помощь во время боя в банке и при наличии палатке в инвентаре даёте +1/2/3 защиты Теперь палатка при хиле накладывает и щит поглощающий урон. Чем выше левел юнита тем сильнее щит. Так же чем больше юнитов, тем щит сильнее Формула (5 + левелНавыка*5)*левелЮнита + (кол-воЮнитов / 5 * левелЮнита) Округляет в большую сторону. Примеры: 1000 скелетов = 220хп 44 виверны = 174хп 10 титанов = 154хп 1 титан = 147хп При накладывании щита на юнита с фул здоровьем - щит действует в пол силы. Кол-во поглощаемого урона пишется с квадратных скобках, рядом с текущим Для этого переименовано было поле "Текущее здоровье" в "Текущее ХП", что бы поместилось значение Для героя со специализацией на палатке левелЮнита в форуме увеличивается на 1. Так же щит всегда в полную силу действует Дипломатия: Навык переработан. Юниты более не присоединяются никогда. При этом снижение требования -2 левела при посещении либы за каждый уровень навыка дипломатии - осталось Так же осталось снижение цены капитуляции Теперь дипломатия увеличивает силу войск в глазах монстров на 10/20/30% при расчёте побега и на сколько стаков будет делиться при бое (так же корректно действует на предпросмотр ворами или магией) Так же позволяет сдаваться нейтралам со скидкой в 70/80/90% Посещение либы даёт бонусный +1 к статам. Т.е. +3 ко всему, вместо +2 Кроме того, после посещения либы даётся +1/2/3 морали до след. битвы Арты дипломатии: Каждый арт снижает стоимость откупа на 10%, действует на нейтралов тоже. Минимальная цена 0 голды Каждый арт снижает требования левела для библиотеки на 1левел. Вне зависимости имеется навык или нет Каждый арт повышает силу армии в глазах монстров на 10% при расчёте побега или деления на кол-во стаков Орлиный глаз: шанс выпадения всем героям (кроме причала ХотЫ) сделал = 0 Всем классическим банкам изменил процент выпадения минималок, максималок... (Т) Был 30-30-30-10% Стал 15-35-35-15% Т.о. вероятность выпадения только минималок снижена. Смещено ближе к центру Арты: Сапоги скороходы теперь J (поднял по уровню) Сумка + 1000 голды N. такой же уровень со всеми сумками голды На данный момент пока что всё. В силу определённых причин уделять время в ближайшее время не выйдет. Потому выкладываю весь код который имеется и добавлю что хотелось бы видеть. Если кто это реализует - обязательно включу в мод 1. для дипломатии сделать +1 к выбраной хар-ке при посещении объектов за 1000 голды. При этом изменить стоимость до 1500/1000/500 2. орлиный глаз. Для лучников сделать +1/2/3 клетки к прямой стреле, возможность просмотра кол-ва юнитов и действие в случае нападения (как у воров) на основании СП 3. Арты, идея в следующем, если ты дрался за арт, то он должен давать бонус. - Все бонусы к стрельбе что бы работали и без навыка - Арты орлиного глаза добавляли +5 к радиусу превью (имеется ввиду дальность бонуса, как у воров) - арты некромантии, если герой без этого навыка, что бы наносил х2 от бонуса арта по андедам, если противник не герой. Т.к. только по нейтральным войскам 4. Волшебное зеркало что бы было массовым, но основной эффект был только на изначальную цель. Остальные получали бы 10/15/20% сопротивления магии 5. Защите от магии выдать так же защиту от огня. Драконам тоже (что бы огненый щит не наносил огненого урона юнитам с иммунитетом к магии) 6. убрать баллистику или объеденить с артилерией 7. навык "убрать преграду", уменьшить в манакосте и что бы убиралась только 1 клетка под курсором. Убрать можно только граничащую с картой клетку (во избежание абуза, аля портануть лучника в недосягаемую точку и убивать милишников) 8. Для "плаща короля нечести" сделать следующий бонус - так же воскрешает на эксперте личей, но сам арт будет давать суммарно навык некромантии равный статическому проценту. Какой процент - надо тестить, но думаю 10+-. Т.е. был навык некромантии 60% с разобранным плащём, собрав получится только 10, но ресать вместо скелетов будет личей 9. Грамотность. Для героя у которого сумма статов выше чем 20 что бы грамотность давала +3/6/9 знания. Проблема в том, что не совсем понимаю куда это привязать и как делать корректный расчёт. Идея есть, но как реализовать понятия не имею. Так что этот пункт пока что на уровне идеи Если вы считаете что некоторые значения не подходят, код ниже прилагаю. Его можете легко изменить и поднастроить всё именно так, как вам кажется более верно Информация как редактировать имеется в этой теме: http://forum.df2.ru/index.php?showtopic=69...mp;#entry711673 Код: CODE #include "../../patcher_x86.hpp" #include <cmath> #include <stdio.h> Patcher* _P; PatcherInstance* _PI; int BuildDepends_Castle[] = { 0, -1, 1, 0, -1, 2, 1, -1, 3, 2, -1, 6, -1, 5, -1, 22, 5, -1, 14, -1, 15, 14, -1, 16, -1, 17, 6, -1, 7, -1, 8, 7, -1, 9, 8, -1, 11, 5, -1, 12, 11, 16, 0, 14, -1, 13, 12, 9, -1, 30, 7, -1, 37, 30, -1, 31, 30, -1, 38, 31, -1, 33, 30, 16, -1, 40, 33, -1, 32, 33, -1, 18, 32, -1, 39, 32, -1, 19, 39, -1, 21, 33, -1, 35, 21, -1, 42, 35, -1, 34, 33, 0, -1, 41, 34, -1, 36, 34, 1, -1, 43, 36, 2, -1, 26, -1, -100 }; int BuildDepends_Inferno[] = { 7, -1, 21, 7, -1, 8, 7, -1, 22, 8, -1, 9, 8, -1, 5, -1, 16, -1, 14, -1, 15, 14, -1, 0, -1, 23, 0, -1, 1, 0, -1, 2, 1, -1, 3, 2, -1, 4, 3, -1, 11, 5, -1, 12, 11, 16, 14, 0, -1, 13, 12, 9, -1, 30, 7, -1, 18, 30, -1, 37, 30, -1, 19, 37, -1, 32, 30, -1, 24, 32, -1, 39, 32, -1, 25, 39, -1, 31, 30, -1, 38, 31, -1, 33, 31, -1, 40, 33, -1, 35, 33, 0, -1, 42, 35, -1, 34, 33, -1, 41, 34, 0, -1, 36, 35, 33, 5, -1, 43, 36, -1, 26, -1, -100 }; int BuildDepends_Rampart[] = { 7, -1, 8, 7, -1, 9, 8, -1, 5, -1, 16, -1, 14, -1, 15, 14, -1, 0, -1, 1, 0, -1, 2, 1, -1, 3, 2, -1, 4, 3, -1, 17, -1, 21, 17, -1, 11, 5, -1, 12, 11, 0, 16, 14, -1, 13, 12, 9, -1, 30, 7, -1, 37, 30, -1, 31, 30, -1, 18, 31, -1, 22, 18, -1, 38, 31, -1, 19, 38, -1, 32, 30, -1, 39, 32, -1, 34, 32, -1, 24, 34, -1, 41, 34, -1, 25, 41, -1, 33, 32, -1, 40, 33, -1, 35, 33, 34, -1, 42, 35, -1, 36, 35, 0, -1, 43, 36, 2, -1, 26, -1, -100 }; int BuildDepends_Dungeon[] = { 7, -1, 8, 7, -1, 9, 8, -1, 22, -1, 23, -1, 5, -1, 16, -1, 14, -1, 15, 14, -1, 17, 14, -1, 0, -1, 21, 0, -1, 1, 0, -1, 2, 1, -1, 3, 2, -1, 4, 3, -1, 11, 5, -1, 12, 11, 16, 14, 0, -1, 13, 12, 9, -1, 30, 7, -1, 18, 30, -1, 37, 30, -1, 19, 37, -1, 32, 30, -1, 39, 32, -1, 31, 30, -1, 38, 31, -1, 33, 32, 31, -1, 40, 33, -1, 34, 33, -1, 41, 34, -1, 35, 33, -1, 42, 35, -1, 36, 34, 35, 0, -1, 43, 36, 2, -1, 26, -1, -100 }; int BuildDepends_Stronghold[] = { 7, -1, 17, 7, -1, 23, 7, -1, 8, 7, -1, 9, 8, -1, 5, -1, 16, -1, 22, 16, -1, 14, -1, 15, 14, -1, 21, 14, -1, 0, -1, 1, 0, -1, 2, 1, -1, 11, 5, -1, 12, 11, 0, 14, 16, -1, 13, 12, 9, -1, 30, 7, -1, 18, 30, -1, 37, 30, -1, 19, 37, -1, 31, 30, -1, 38, 31, 37, -1, 34, 31, -1, 41, 34, -1, 36, 34, 35, -1, 43, 36, -1, 32, 30, -1, 39, 32, 16, -1, 33, 32, -1, 40, 33, 0, -1, 35, 32, 34, -1, 42, 35, -1, 26, -1, -100 }; int SecondarySkills_Mysticism[] = { 1, 7, 14, 20 }; int SecondarySkills_Estates[] = { 0, 250, 500, 750 }; float SecondarySkills_Necromancy[] = { 0, 0.15, 0.30, 0.45 }; float SecondarySkills_Resistance[] = { 0, 0.15, 0.25, 0.35 }; float SecondarySkills_Sorcery[] = { 0, 0.1, 0.2, 0.3 }; float SecondarySkills_Learning[] = { 0, 0.15, 0.3, 0.45 }; int __stdcall spellSlow(LoHook* h, HookContext* c) { float speed = (float)(*(int*)(c->ecx +196)); c->eax = floor( (speed * (*(float*)(c->ecx + 1224))) + 0.5 ); c->return_address = 0x448A2E; return NO_EXEC_DEFAULT; } int __stdcall spellSlowMelee(LoHook* h, HookContext* c) { float speed = (float)(*(int*)(c->esi +196)); c->eax = floor( (speed * (*(float*)(c->esi + 1224))) + 0.5 ); c->return_address = 0x441E2D; return NO_EXEC_DEFAULT; } int __stdcall libraryVisit(LoHook* h, HookContext* c) { if (*(char*)(c->esi + 201 + 4) > 0) { char bonus = 1; *(char*)(c->esi + 1142) += bonus; // атака *(char*)(c->esi + 1143) += bonus; // защита *(char*)(c->esi + 1144) += bonus; // колд. сила *(char*)(c->esi + 1145) += bonus; // знания } if (*(char*)(c->esi + 201 + 4) > 0) { char moreleBonus = *(char*)(c->esi + 201 + 4); *(char*)(c->esi + 282) += moreleBonus; } return EXEC_DEFAULT; } float __stdcall getArtArmyValueModifier(int art[]) { for (int i = 0; i < 19; ++i) { if ( art[i] == 66 ) { return 30; } } return 0; } float __stdcall getArmyValueModifierOld(int diplomacyLevel, HookContext* c) { float armyModifier[4] = {0.00, 0.10, 0.15, 19.00}; float currentModifier = ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModifier[diplomacyLevel] : 1 ); return currentModifier; } float __stdcall getArmyValueModifier(int baseHeroOffset) { int diplomacyLevel = (int)(*(char*)(baseHeroOffset + 201 + 4)); float armyModifier[4] = {0.00, 0.10, 0.2, 0.3}; float currentModifier = ( (diplomacyLevel >= 0) && (diplomacyLevel <= 3) ? armyModifier[diplomacyLevel] : 0 ); float armyArtModifier = 0; for (int i = 0; i < 19; ++i) { if ( *(int*)(baseHeroOffset + 301 + (i << 3)) == 66 ) { armyArtModifier += 0.1; } if ( *(int*)(baseHeroOffset + 301 + (i << 3)) == 67 ) { armyArtModifier += 0.1; } if ( *(int*)(baseHeroOffset + 301 + (i << 3)) == 68 ) { armyArtModifier += 0.1; } } 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; } int __stdcall setSurrenderButton(LoHook* h, HookContext* c) { int heroOffset = *(int*)(c->esi + c->eax * 4 + 0x53CC); if ( heroOffset == 0 ) { return EXEC_DEFAULT; } char diplomacyLevel = *(char*)(*(int*)(c->esi + c->eax * 4 + 0x53CC) + 201 + 4); if ( diplomacyLevel > 0 ) { c->return_address = 0x477EB5; return NO_EXEC_DEFAULT; } return EXEC_DEFAULT; } int __stdcall setSurrenderPrice(LoHook* h, HookContext* c) { //if ( *(int*)(*(int*)0x699420 + 0x132C0) == 0 ) { int combatManager = *(int*)0x699420; if ( *(int*)(combatManager + (0x14F4 - *(int*)(combatManager + 0x132C0)) * 4) == 0 ) { switch ( (char)c->ecx ) { case 1: *(float*)&c->edx = 0.7f; break; case 2: *(float*)&c->edx = 0.8f; break; case 3: *(float*)&c->edx = 0.9f; break; default: c->edx = 0; } c->return_address = 0x4E480B; return NO_EXEC_DEFAULT; } return EXEC_DEFAULT; } int __stdcall setSurrenderMinPrice(LoHook* h, HookContext* c) { int cmAddr = *(int*)0x699420; // адрес combatManager int side = *(int*)(cmAddr + 0x132C0); // сторона в битве (0 - левая, 1 - правая) float minimumPrice; if ( *(int*)(cmAddr + (0x14F4 - side) * 4) == 0 ) minimumPrice = 1.0f; else minimumPrice = 0.9f; if ( *(float*)(c->ebp - 4) > minimumPrice ) { *(float*)(c->ebp - 4) = minimumPrice; } c->return_address = 0x4E493F; return NO_EXEC_DEFAULT; } int __stdcall setLibraryVisitLevel(LoHook* h, HookContext* c) { int allLevelBonuses = 0; if (*(short*)(c->esi + 85) < 10) { for (int i = 0; i < 19; ++i) { switch ( *(int*)(c->esi + 301 + (i << 3)) ) { case 66: allLevelBonuses += 1; break; case 67: allLevelBonuses += 1; break; case 68: allLevelBonuses += 1; break; } } if (*(char*)(c->esi + 201 + 4) > 0) { allLevelBonuses += *(char*)(c->esi + 201 + 4) * 2; } } int currentLevel = *(int*)(c->esi + 85); c->eax = currentLevel + allLevelBonuses; c->return_address = 0x4A2F55; return NO_EXEC_DEFAULT; } int __stdcall setBaseHeroSpeed(LoHook* h, HookContext* c) { c->ecx += *(char*)(c->ebx + 201 + 0); return EXEC_DEFAULT; } int __stdcall setBankUnitBonus(LoHook* h, HookContext* c) { int cmAddr = *(int*)0x699420; int heroOffset = *(int*)(cmAddr + 0x53CC); if (*(int*)(c->ebp + 16) != heroOffset) { return EXEC_DEFAULT; } if ( *(char*)(*(int*)0x699420 + 0x53C5) == 1) { // проверка что бой в банке существ if(*(char*)(heroOffset + 201 + 19) > 0) { // проверка на тактику *(int*)(c->ebx + 196) += *(char*)(heroOffset + 201 + 19); } if(*(char*)(heroOffset + 201 + 20) > 0) { //проверка на артиллерию if ( *(char*)(heroOffset + 301 + (13 << 3)) != -1 ) { //13 - слот на кукле для баллисты. -1 - пустой слот *(int*)(c->ebx + 200) += *(char*)(heroOffset + 201 + 20); } } if(*(char*)(heroOffset + 201 + 27) > 0) { //проверка на первую помощь if ( *(char*)(heroOffset + 301 + (15 << 3)) == 6 ) { //15 - слот на кукле для палатки. 6 - айди палатки *(int*)(c->ebx + 204) += *(char*)(heroOffset + 201 + 27); } } } return EXEC_DEFAULT; } int __stdcall resetTacticsUnitSpeedBonus(LoHook* h, HookContext* c) { int cmAddr = *(int*)0x699420; if ( *(char*)(cmAddr + 0x53C5) == 1) { // проверка что бой в банке существ char tacticLevel = *(char*)(*(int*)(cmAddr + 0x53CC) + 201 + 19); int roundNumber = *(int*)(cmAddr + 0x132A0) - 30000; if ((tacticLevel > 0) && (roundNumber == 1)) { if ( c->ebx == cmAddr + 0x132A0 ) { *(int*)(c->ecx + 196) -= tacticLevel; } } } return EXEC_DEFAULT; } int __stdcall spellPray(LoHook* h, HookContext* c) { c->ecx += 2; c->ebx += 2; int cmAddr = *(int*)0x699420; char waterLevel = *(char*)(*(int*)(cmAddr + 0x53CC) + 201 + 16); if (waterLevel > 1) { *(int*)(c->esi + 0x458) = 1; } return EXEC_DEFAULT; } int __stdcall spellPrayEnd(LoHook* h, HookContext* c) { c->ecx -= 2; c->ebx -= 2; return EXEC_DEFAULT; } int __stdcall spellPrayBonus(LoHook* h, HookContext* c) { int spellDuration = *(int*)(c->ecx + 0x258); // Prayer bool isUndead = *(int*)(c->ecx + 0x84) & 0x40000; if (spellDuration != 0 && !isUndead) { // проверяем Prayer и бит Undead c->eax = 1; } return EXEC_DEFAULT; } int __stdcall preCalculateDmg(LoHook* h, HookContext* c) { int cmAddr = *(int*)0x699420; int heroOffset = *(int*)(cmAddr + 0x53CC); return EXEC_DEFAULT; } int __stdcall setFirstAidBonus(LoHook* h, HookContext* c) { int cmAddr = *(int*)0x699420; int heroOffset = *(int*)(cmAddr + 0x53CC); if(*(char*)(heroOffset + 201 + 27) > 0) { //проверка на первую помощь if ( *(char*)(heroOffset + 301 + (15 << 3)) == 6 ) { //15 - слот на кукле для палатки. 6 - айди палатки *(int*)(c->ebx + 204) += *(char*)(heroOffset + 201 + 27) * 2; } } return EXEC_DEFAULT; } int __stdcall setFirstAidShield(LoHook* h, HookContext* c) { int cmAddr = *(int*)0x699420; float stackBonusModificator = 5.0f; int currentSide = *(int*)(cmAddr + 0x132C0); int heroAddr = *(int*)(cmAddr + currentSide * 4 + 0x53CC); // адрес героя с учётом стороны char firstAidLevel = *(char*)(heroAddr + 201 + 27); int heroID = *(int*)(heroAddr + 26); int specInfoAddr = *(int*)0x679C80; bool firstAidSpec = *(int*)(specInfoAddr + heroID * 40) == 0 && *(int*)(specInfoAddr + heroID * 40 + 4) == 27; int specBonus = 0; if (firstAidSpec) { specBonus += 1; } int unitLevel = *(int*)(c->esi + 0x78) + 1 + specBonus; int firstAidBonus = (5 + firstAidLevel * 5) * unitLevel; int countMonsters = *(int*)(c->esi + 0x4C); float countUnitsForShield = ceil(countMonsters / stackBonusModificator); int countUnitBonus = countUnitsForShield * unitLevel; int totalSheildCount = firstAidBonus + countUnitBonus; if (*(int*)(c->esi + 0x58) == 0 && !firstAidSpec) { totalSheildCount = totalSheildCount / 2; } *(int*)(c->esi + 0x94) = totalSheildCount; return EXEC_DEFAULT; } int __stdcall absorbDamage(LoHook* h, HookContext* c) { if ( c->ecx <= *(int*)(c->esi + 0x94) ) { *(int*)(c->esi + 0x94) -= c->ecx; c->ecx = 1; } else { c->ecx -= *(int*)(c->esi + 0x94); *(int*)(c->esi + 0x94) = 0; } return EXEC_DEFAULT; } int __stdcall getStackHp(LoHook* h, HookContext* c) { int unitAddr = *(int*)(c->ebp - 0x20); int hpShieldValue = *(int*)(unitAddr + 0x94); if ( hpShieldValue > 0 ) { sprintf( (char*)0x697428, "%d [%d]", *(int*)(c->ebp + 8), hpShieldValue ); // display left hp [shield] } else { return EXEC_DEFAULT; } c->esp -= 12; // adjust esp* c->return_address = 0x5F64C2; return NO_EXEC_DEFAULT; } int __stdcall checkAllowHeal(LoHook* h, HookContext* c) { int cmAddr = *(int*)0x699420; int currentSide = *(int*)(cmAddr + 0x132C0); int heroAddr = *(int*)(cmAddr + currentSide * 4 + 0x53CC); // адрес героя с учётом стороны if (*(char*)(heroAddr + 201 + 27) == 0) { return EXEC_DEFAULT; } c->return_address = 0x4738C3; return NO_EXEC_DEFAULT; } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { static _bool_ plugin_On = 0; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: if (!plugin_On) { plugin_On = 1; _P = GetPatcher(); _PI = _P->CreateInstance("HD.Plugin.DedMorozzz"); *(int*)0x4EB816 = (int)BuildDepends_Castle; *(int*)0x4EB8B3 = (int)BuildDepends_Rampart; *(int*)0x4EBA39 = (int)BuildDepends_Inferno; *(int*)0x4EBA5C = (int)BuildDepends_Dungeon; *(int*)0x4EBA70 = (int)BuildDepends_Stronghold; *(int*)0x4E41C8 = (int)SecondarySkills_Mysticism; *(int*)0x4E461E = (int)SecondarySkills_Estates; *(int*)0x4E4AC4 = (int)SecondarySkills_Learning; *(int*)0x4E5B2C = (int)SecondarySkills_Sorcery; *(int*)0x4E4967 = (int)SecondarySkills_Resistance; //Necromancy *(int*)0x4E3F59 = (int)SecondarySkills_Necromancy; *(int*)0x4E3FE7 = 0x63EAE4; //amulet 0.05 *(int*)0x4E402D = 0x63B8D0; //cloak 0.10 *(int*)0x4E4074 = 0x63EB28; //boots 0.15 *(int*)0x4E4100 = 0x63B8D0; //amplifier 0.10 //specialization bonuses. Set 0.02 *(int*)0x4E3F92 = 0x63AC60; //Necromancy *(int*)0x4E4F1E = 0x63AC60; //Logistic *(int*)0x4E4569 = 0x63AC60; //Attack *(int*)0x4E45C9 = 0x63AC60; //Defence _PI->WriteLoHook(0x448A1A, spellSlow); _PI->WriteLoHook(0x441E19, spellSlowMelee); _PI->WriteDword((0x417236 + 1), 3); // при ПКМ _PI->WriteHexPatch((0x4A755D), "EB"); // проходим мимо бесплатного присоединения _PI->WriteHexPatch((0x4A75A9), "EB"); // проходим мимо платного присоединения _PI->WriteHexPatch(0x417234, "EB"); // проходим мимо бесплатного присоединения (preview) _PI->WriteHexPatch(0x417246, "EB"); // проходим мимо платного присоединения (preview) _PI->WriteLoHook(0x4A7441, setArmyValue); _PI->WriteLoHook(0x4171E6, setArmyValuePreview); _PI->WriteLoHook(0x4AC35E, setArmyValueSplit); _PI->WriteLoHook(0x477EA9, setSurrenderButton); _PI->WriteLoHook(0x4E4804, setSurrenderPrice); _PI->WriteLoHook(0x4E4931, setSurrenderMinPrice); _PI->WriteLoHook(0x4A2F92, libraryVisit); _PI->WriteLoHook(0x4A2F47, setLibraryVisitLevel); _PI->WriteLoHook(0x4E4ED9, setBaseHeroSpeed); _PI->WriteLoHook(0x43D492, setBankUnitBonus); _PI->WriteLoHook(0x475A3D, resetTacticsUnitSpeedBonus); _PI->WriteLoHook(0x44493C, spellPray); _PI->WriteLoHook(0x4443F1, spellPrayEnd); _PI->WriteLoHook(0x442F6A, spellPrayBonus); _PI->WriteLoHook(0x478552, setFirstAidShield); _PI->WriteLoHook(0x443DBB, absorbDamage); _PI->WriteLoHook(0x5F64AF, getStackHp); _PI->WriteHexPatch(0x47609A, "9090"); _PI->WriteLoHook(0x4738AC, checkAllowHeal); /* ---------------------------------------- --- CmManager. Base address = 699420 --- ---------------------------------------- */ } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } Лод файлы выложу чуток позжее. Планирую завтра Так же огромное спасибо AlexSpl, который помогал по огромному кол-ву моментов и тов-щу igrik На этом пока что всё Пользуйтесь
Прикрепленные файлы
Спасибо сказали: |
|
|
Текстовая версия | Сейчас: 19 April 2024 - 07:50 |
Copyright by Алексей Крючков
Programming by Degtyarev Dmitry |