IPB

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

> Джебус мод, баланс мод для шаблона джебус
DedMorozzz
сообщение 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. такой же уровень со всеми сумками голды



На данный момент пока что всё. В силу определённых причин уделять время в ближайшее время не выйдет. Потому выкладываю весь код который имеется и добавлю что хотелось бы видеть. Если кто это реализует - обязательно включу в мод =).gif
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

На этом пока что всё smile.gif Пользуйтесь
Прикрепленные файлы
Прикрепленный файл  jebusMod.rar ( 5.5 килобайт ) Кол-во скачиваний: 215
 
Go to the top of the pageAdd Nick
 
+Quote Post

Сообщений в этой теме
- DedMorozzz   Джебус мод   05 Feb 2017, 00:04
- - hippocamus   Удивило вот это: Цитата(DedMorozzz @ 05 Feb 2...   05 Feb 2017, 01:07
|- - DedMorozzz   Цитата(hippocamus @ 05 Feb 2017, 00:07) У...   05 Feb 2017, 01:25
- - the_new_pirate   > Обнулил только для "стандартных" за...   05 Feb 2017, 12:43
|- - DedMorozzz   Цитата(the_new_pirate @ 05 Feb 2017, 11:4...   05 Feb 2017, 17:21
|- - hippocamus   Цитата(DedMorozzz @ 05 Feb 2017, 17:21) П...   05 Feb 2017, 19:30
- - AlexejKa83   Кому не нужны все изменения сразу, разбил плагин D...   05 Feb 2017, 16:52
- - serovoy   Цитата(DedMorozzz @ 05 Feb 2017, 03:04) Т...   05 Feb 2017, 22:44
|- - DedMorozzz   Цитата(serovoy @ 05 Feb 2017, 21:44) Цита...   05 Feb 2017, 23:10
|- - hippocamus   Цитата(DedMorozzz @ 05 Feb 2017, 23:10) В...   05 Feb 2017, 23:15
- - hippocamus   serovoy, подобным путём можно зависимость морали о...   05 Feb 2017, 23:03
- - AlexSpl   Отформатировать исходный код не помешало бы. Лучше...   05 Feb 2017, 23:23
|- - DedMorozzz   Цитата(AlexSpl @ 05 Feb 2017, 22:23) Отфо...   05 Feb 2017, 23:26
- - serovoy   Цитатаразве не так? smile.gifЕсли бы это было так,...   05 Feb 2017, 23:25
|- - DedMorozzz   Цитата(serovoy @ 05 Feb 2017, 22:25) Цита...   06 Feb 2017, 01:56
- - AlexejKa83   Если я не ошибаюсь, но в rmg.txt джебуса до сих по...   05 Feb 2017, 23:31
- - AlexSpl   КодКод А текстовики можно отдельно положить. У н...   05 Feb 2017, 23:31
- - DedMorozzz   хз... вот обернул и не работает У кого есть права ...   05 Feb 2017, 23:33
- - AlexSpl   Хм, действительно, если вставить код, отображается...   05 Feb 2017, 23:45
- - hippocamus   Работает. Только нужно использовать тег "code...   05 Feb 2017, 23:54
- - AlexejKa83   Баг с палаткой первой помощи у героев с навыком ПП...   09 Feb 2017, 07:53
- - igrik   Я уже описывал причину DedMorozzz'у или AlexSp...   09 Feb 2017, 09:34
- - DedMorozzz   AlexejKa83, да, эти ф-ии не нужны. Ну как не нужны...   09 Feb 2017, 21:32
- - AlexSpl   Таки посмотрел "Щит ХП". Имба ещё та. Мо...   12 Feb 2017, 21:52
|- - AlexejKa83   Цитата(AlexSpl @ 12 Feb 2017, 21:52) Таки...   12 Feb 2017, 22:39
- - DedMorozzz   надо будет подумать как сделать, если есть идеи - ...   14 Feb 2017, 00:55
- - AlexejKa83   Новая формула выглядит лучше. Вот только копейщик...   14 Feb 2017, 19:54
- - swallowmee   С какой последней версией ХоТА может использоватьс...   09 Apr 2019, 16:29


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 19 April 2024 - 07:50
Copyright by Алексей Крючков
Strategy Gamez by GrayMage
Programming by Degtyarev Dmitry
  Яндекс.Метрика