Чёртос-2 (Chortos-2)
24 Sep 2007, 21:39
Предлагаю всем, у кого есть какая бы то ни была информация о технической стороне игры, поделиться ею.
Обсуждение в
соответствующей теме.
sergroj
28 Sep 2007, 21:30
Таблица монстров состоит из таких структур: (одинакова для игры и редактора карт)
Код
Town: int;
Level: int;
SoundName: PChar; // 4 буквы, с которых начинаются звуки монстра
DefName: PChar;
Flags: int;
Name: PChar;
PluralName: PChar;
Features: PChar; // (описание способностей)
CostWood: int;
CostMercury: int;
CostOre: int;
CostSulfor: int;
CostCrystal: int;
CostGems: int;
CostGold: int;
FightValue: int;
AIValue: int;
Growth: int;
HordeGrowth: int;
HitPoints: int;
Speed: int;
Attack: int;
Defence: int;
DamageLow: int;
DamageHigh: int;
Shots: int;
Spells: int;
AdvLow: int; // ?
AdvHigh: int; // ?
В файле h3wog.exe таблица стандартных монстров находится по адресу $2703B8, а новые монстры - $31C188.
Таблица артефактов (проверял только в редакторе)
Код
ArTraits: array[0..6] of int;
CantAdd: int;
ArTraits я не описывал, но он полностью соответствует столбцам файла ArTraits.txt
CantAdd - если не 0, то в Редакторе карт артефакт не показывается в списке тех, которые можно дать герою, поставить наградой за задание провидца и т.п.
sergroj, зачет!
Добавлю то, что известно мне.
1. Структура h3wog.exe 3,57
Как я понял, h3wog.exe представляет собой два склееных исполняемых файла - обычный heroes3.exe с определенными изменениями и некую DLL. Базовый адрес загрузки первого - 400000h, второго - 465000h, то есть байт в позиции А в h3wog.exe загружается по адресу:
400000 + А, если А < 29B000,
465000 + А, если А >= 29B000.
(на всеобъемность не претендую, там могут быть другие сегменты)
2. Массив дескрипторов существ
Массив параметров старых существ (SoD) хранится по адресу exe:2703B8 (mem:6703B8) и содержит 150d записей по 74h байта.
Массив параметров новых существ (WoG) хранится по адресу exe:2DE1C8 (mem:7431C8) и содержит 42d записи.
При инициализации (сразу после старта героев, до видеозаставки) эти массивы копируются в один общий массив длиной 192 записи, располагающийся по адресу mem:776F68 - видимо, он и используется в игре.
Структура записи:
DWORD мировоззрение (0 - замок);
DWORD уровень (0 - первый, 6 - седьмой, максимальный (даже у лазурных));
DWORD префикс звуковых файлов (указатель на Zero-terminated строку из 4-х символов);
DWORD имя дефа; (указатель на строку; например, "crgrif.def")
DWORD флаги; (см. ERM helр, !!MA:X)
указатели содержат адреса в памяти, а не в файле (см. п 1)
остальные параметры грузятся из файла или используются по-другому.
3. Копирование массивов
При инищиализации участок кода около 703812 копирует массивы по специальной таблице, находящейся по 745F90. Таблица состоит из записей вида:
DWORD pSrc; // откуда копировать
DWORD pDest; // куда
DWORD cbSize; // размер в байтах
последний элемент таблицы состоит из трех нулей.
Например, есть запись (6703B8, 776F68, 43F8) - копирование массива старых существ (адрес записи 746038).
4. Массив обитателей жилищ
По адресу 63D570 (копируется в 7AF0B0) лежит таблица обитателей генераторов существ (объект на карте) - массив двойных слов. Генератор - тип объекта 17, подтип объекта - индекс в этом массиве.
5. Огненный щит
За наличие огненного щита у султанов Эфритов ответственны две проверки:
:004225D6 837E3435 cmp dword ptr [esi+34], 00000035
:004225DA 740A je 004225E6
и
:00442E61 83793435 cmp dword ptr [ecx+34], 00000035
:00442E65 7507 jne 00442E6E
(35h - Султан-Эфрит). То есть, поменяв эти команды, можно снабдить встроенным огненным щитом другой контингент.
Обнаружены также проверки на тип существа для регенерации, отсоса 2х очков маны и ненависти.
sergroj
29 Sep 2007, 21:37
1. На самом деле, Славин файл - это exe.
Для WoG 3.58f:
400000 + А, если А < 29C000,
465000 + А, если А >= 29C000.
2.
Для WoG 3.58f:
Массив новых существ стоит в exe по адресу 31C188
Остальное не проверял.
Чёртос-2 (Chortos-2)
30 Sep 2007, 20:50
Всё для WoG 3.58f.
Все адреса указаны в шестнадцатиричной системе счисления и являются виртуальными адресами с image base (400000). Когда числа указаны в формате «от … до …», оба конца отрезка берутся включительно.
Таблица с типами стрелковых снарядов (стрел и т. п.) для стандартных существХранится в адресах 00797BB8–00797C7B (неиспользующаяся оригинальная — 0043DBA4–0043DC34). На каждое существо отводится один байт с номером типа снаряда. Таблица начинается с лучника (существо № 2) и заканчивается неким существом № 197 (оригинальная — баллистой, существом № 146).
Имена изображений стрелковых снарядов (стрел и т. п.)В адресах 0043DAAA–0043DB1C расположен оператор выбора (switch для любителей C‐подобных языков, case для любителей Pascal‐подобных). Он содержит 16 имен DEF‐файлов (для
типов снаряда №№ 00–0Fh), плюс один дополнительный пункт, выполняемый по умолчанию, то есть для всех остальных типов снаряда. При запуске WoG код оператора изменяется так, чтобы для типа 01 совершался прыжок на 007649D0, где проводится проверка на драколича — если это существо № 196, используется изображение дыхания драколича, если нет — стандартное изображение стрелы лучника из замка.
SUB_L004F6C00, функция отображения сообщенияКод
enum msg_type: long
{
MSG_OK = 1,
MSG_YES_NO = 2,
MSG_RIGHT_CLICK = 4,
};
// Display a message
fastcall void SUB_L004F6C00(const char *text, msg_type type, int, int, int, int, int, int, int, int, int, int);
// Example (taken from 004F879A):
SUB_L004F6C00("This game runs in 65536 color mode. You must switch the desktop to this mode before playing the game.", MSG_OK, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0);
Есть идея, что таинственные аргументы −1 и 0 могут являться типами и подтипами изображений (как в ERM у !!IF:M и !!IF:Q).
SUB_L0050CEA0, функция смены курсора мышиКод
enum pointer_type: long
{
POINTER_DEFAULT,
POINTER_ADVMAP,
POINTER_COMBAT,
POINTER_SPELL, // This is an animated pointer, subtype = frame index
POINTER_ARTIFACT,
};
// Change the mouse pointer
pascal void SUB_L0050CEA0(pointer_type type, int subtype);
Непонятные функцииКод
// Get a text file from the bitmap LOD (details not found out yet)
// If unsuccessful (?), returns NULL
cdecl char *SUB_L0055BFE0(const char *filename);
// ?? Do something with a creature-related sound;
// pattern like '%sshot.82M'
void SUB_L006179DE(void *, const char *pattern, int);
По адресу 00559390 что‑то делается с LOD‐файлами.
Координаты строений в городе
по смещению 0x0028AA0c + (44 * Town + Area) * 6 содержится структура вида:
WORD frames
WORD x
WORD y
frames - число кадров в анимации (или состояний, как, например, для верфи)
См. форматы Т (Town Types), CMI (Item/area of the Town Screen)
Примеры:
TBTWTVRN.DEF - Tower Tavern (5) - (375, 278) = (0x177, 0x116)
*0x0028AC3C = 77 01 16 01
TBTWCSTL.def - Tower Fort(7) - (304, 0) = (0x130, 0)
*0x0028AC48 = 30 01 00 00
TBTWDW_0.def - Gremlins Dwelling (30) - (453, 221) = (0x1C5, 0xDD)
*0x0028ACD2 = C5 01 DD 00
Tower Mage Guild 1 (0) - (597, 82) = (0x255, 0x52)
*0x0028AC1E = 55 02 52 00
TBFRDW_0.DEF - Gnoll Dwelling (30) - (641, 168) = (0x281, 0xA8)
*0x0028B1FA = 81 02 A8 00
Поле frames
Castle:
00 0 Level 1 Mage Guild
00 1 Level 2 Mage Guild
0B 2 Level 3 Mage Guild
0B 3 Level 4 Mage Guild
00 4 Level 5 Mage Guild
00 5 Tavern
02 6 Shipyard (Castle, Fortress, Necropolis)
00 7 Fort
00 8 Citadel
00 9 Castle
0A 10 Village Hall
0A 11 Town Hall
0A 12 City Hall
0A 13 Capitol
00 14 Marketplace
00 15 Resource Silo
00 16 Blacksmith
14 17 Special Building: Lighthouse
00 18 Horde Building: Griffin Bastion
00 19 Upgraded Dwelling with Horde Building (see 18 for particulars)
02 20 ?
00 21 Special Building: Stables
00 22 Special Buildings: Brotherhood of the Sword
0A 23 Special Building: NFA: Waterfall
00 24 Horde Building 2: None
Fortress
00 0 Level 1 Mage Guild
00 1 Level 2 Mage Guild
15 2 Level 3 Mage Guild
00 3 Level 4 Mage Guild
00 4 Level 5 Mage Guild
15 5 Tavern
00 6 Shipyard (Castle, Fortress, Necropolis)
00 7 Fort
00 8 Citadel
15 9 Castle
00 10 Village Hall
Рекомендую редактор двоичных файлов 010 Editor. Там куча разных функций, и, в частности, С-подобный язык скриптов и описания шаблонов. Вот пример шаблона для h3wog.exe, содержащий некоторые массивы, относящиеся к строениям в городе:
(объявление переменной соответсвует чтению ее из текущего места в файле)
Код
// Common definitions
// Map memory pointer to file offset
DWORD MemToFile( DWORD p )
{
return p < 0x69B000 ? p - 0x400000 : p - 0x465000;
}
// Pointer to zero-terminated string
typedef DWORD StringPtr <read=ReadStringPtr>;
string ReadStringPtr( StringPtr &p )
{
return ReadString(MemToFile(p));
}
// Town screen areas DEF's
// TB##$$$$
// ## - Town code, $$$$ - Building code, ".DEF" omitted
FSeek(0x00243074);
struct
{
StringPtr townBuildings[44];
} townsBuildings[9];
// Town screen areas outline and mask bitmaps
// TO#$$$$$ or TO##$$$$
// # - Town code, $ - Building code, ".pcx" omitted
// Used for TO*.pcx and TZ*.pcx
FSeek(0x0028A3DC);
struct
{
StringPtr townBuildingOutlines[44];
} townsBuildingOutlines[9];
// Town building icons
// BO##$$$$.pcx
// # - Town code, $ - Building code
FSeek(0x002755B8);
struct
{
StringPtr townBuildingIcons[44];
} townsBuildingIcons[9];
// Town screen areas placement
FSeek(0x0028AA0c);
struct AreaPos
{
WORD frames; // Animation frames count or states count
WORD x, y;
};
struct
{
AreaPos buildingPositions[44] <read=ReadAreaPos>;
} townsBuildingPositions[9];
string ReadAreaPos( struct AreaPos &fxy )
{
string s;
SPrintf(s, "(%d, %d), %d frames", fxy.x, fxy.y, fxy.frames);
return s;
}
// Buildings list per town, order seems arbitrary
enum <byte> TownArea
{
Mage1,
Mage2,
Mage3,
Mage4,
Mage5,
tavern,
shipyard,
fort,
citadel,
castle,
village_hall,
town_hall,
city_hall,
capitol,
marketplace,
silo,
blacksmith,
special1,
horde1,
horde1U,
Ship,
special2,
special3,
special4,
horde2,
horde2U,
Grail,
town_houses,
city_houses,
Capitol_houses,
dwelling1,
dwelling2,
dwelling3,
dwelling4,
dwelling5,
dwelling6,
dwelling7,
upgradeddwelling1,
upgradeddwelling2,
upgradeddwelling3,
upgradeddwelling4,
upgradeddwelling5,
upgradeddwelling6,
upgradeddwelling7,
};
FSeek(0x242EC4);
struct
{
TownArea areas[44];
} townsAreas[9];
Здесь описаны спрайты, маски и иконки зданий, а также положение зданий. В массивах последней структуры перечислены номера строений соответсвующего города; порядок, по-видимому, случаен.
В принципе, для добавления отображаемого спрайта строения нужно:
- Добавить свободный номер здания (0...43) в townsAreas
- Обеспечить спрайты и маски
- Задать позицию в townsBuildingPositions
Здание на экране появляется. Последствия этого еще предстоит исследовать...
Регенерация существ
002F55C7 83F8 3C CMP EAX,3C //стражи
002F55CA 0F84 BB000000 JE 002F568B
002F55D0 83F8 3D CMP EAX,3D //привидения
002F55D3 0F84 B2000000 JE 002F568B
002F55D9 3D 90000000 CMP EAX,90 //тролли
002F55DE 0F84 A7000000 JE 002F568B
002F55E4 3D 9D000000 CMP EAX,9D //кошмарные гидры
002F55E9 0F84 92000000 JE 002F5681
где 3C, 3D, 90, 9D - номер существа в шестнадцатеричной системе
Для кошмарных гидр выполняется проверка вероятности регенерации
002F5681 E8 9A7EFFFF CALL 002ED520
002F5686 83F8 28 CMP EAX,28
где 28h = 40% вероятность. Ее можно убрать если вместо JE 002F5681 поставить JE 002F568B.
А вот тут находится количество срегенерированных жизней
002F55BC BA 32000000 MOV EDX,32
где 32h = 50 HP.
Атака с возвращением
002F57C6 83F8 48 CMP EAX,48 //гарпия
002F57C9 74 5D JE SHORT 002F5828
002F57CB 83F8 49 CMP EAX,49 //гарпия-ведьма
002F57CE 74 58 JE SHORT 002F5828
002F57D0 3D 9B000000 CMP EAX,9B //темный дракон
002F57D5 74 21 JE SHORT 002F57F8 //доп проверка двуклеточности
Для выбора режима нападения при нажатия правой кнопкой на защите (атаковать и вернуться или атаковать и остаться там)
002FA2D7 837D F0 48 CMP DWORD PTR SS:[EBP-10],48 //гарпия
002FA2DB 74 23 JE SHORT 002FA300
002FA2DD 837D F0 49 CMP DWORD PTR SS:[EBP-10],49 //гарпия-ведьма
002FA2E1 74 1D JE SHORT 002FA300
002FA2E3 817D F0 9B000000 CMP DWORD PTR SS:[EBP-10],9B //темный дракон
002FA2EA 74 14 JE SHORT 002FA300
Возрождение фениксов
002F587C 817E 34 83000000 CMP DWORD PTR DS:[ESI+34],83 //феникс
002F5883 74 38 JE SHORT 002F58BD
002F5885 817E 34 9E000000 CMP DWORD PTR DS:[ESI+34],9E //священный феникс
002F588C 74 1C JE SHORT 002F58AA
Подскажите плиз где идет проверка на высасывание маны привидениями и кастование заклинаний после атаки (единороги, зомби, медузы, василиски, стрекозы и т.д.)
Номер города, у которого Грааль дает все заклинания (0-8, другое значение означает "никакой", по умолчанию 08 - Сопряжение)
BYTE 0x005BE4F6 - влияет на изучение заклинаний героем
BYTE 0x005D743E - влияет на вид заклинания в гильдии
Проблема: остаются подсказки по щелчку/наведению мыши
---
*(DWORD *)0x00699538 + 0x21620 - адрес массива структур Героев
размер структуры 0x492
Т.е.
*(DWORD *)0x00699538 + 0x21620 + 0x492 - по этому адресу располагается структура Валески, и т.д.
Д'якон
17 Nov 2007, 16:00
По указателю 0х004С2001 +224091
содержаться адреса с шагом 4 отвечающие за подсказку в гильдии
Entuser
22 Jan 2008, 11:10
7AD78 - тут в екзишнеке храниться число 5 - после загрузки изменяется на 34(HEX) - влияет на число загружаемых строк в ZCRTRAITS.
mem 007012A4 / file 29C2A4 - изменяет это значение и много других
Чёртос-2 (Chortos-2)
07 Mar 2008, 21:37
Функция проверяет, есть ли у героя заданный артефакт (перед вызовом в ecx кладётся указатель, видимо, на структуру героя):
CODE
unsigned __int8 __stdcall has_artifact_004D9420(int artifact_number)
{
char *hero_struct; // ecx@0
signed int body_slot_number; // eax@1
_DWORD *body_slot_pointer; // edx@1
signed int backpack_slot_number; // eax@4
_DWORD *backpack_slot_pointer; // ecx@4
body_slot_number = 0;
body_slot_pointer = hero_struct + 301;
while ( *body_slot_pointer != artifact_number )
{
++body_slot_number;
body_slot_pointer += 2;
if ( body_slot_number >= 19 ) // Nothing on the body? Look in the backpack then
{
backpack_slot_number = 0;
backpack_slot_pointer = hero_struct + 468;
while ( *backpack_slot_pointer != artifact_number )
{
++backpack_slot_number;
backpack_slot_pointer += 2;
if ( backpack_slot_number >= 64 )
return 0; // Backpack neither => found nothing
}
return 1; // Found the artifact in slot #backpack_slot_number
}
}
return 1; // Found the artifact in slot #body_slot_number
}
Код сгенерирован
Hex-Rays (я переименовал переменные, указал типы указателей так, чтобы не было лишних приведений типов, и добавил комментарии, которые по-английски).
P. S. Чуть не забыл: если возвращается один, значит, артефакт есть, если ноль — значит, его нет. В оригинале наверняка возвращался тип bool.
Бесстрашие
002F7C6C 817F 34 84000000 CMP DWORD PTR DS:[EDI+34],84 //лазурный дракон
002F7C73 74 46 JE SHORT 002F7CBB
002F7C75 817F 34 96000000 CMP DWORD PTR DS:[EDI+34],96 //верховный архангел
002F7C7C 7C 09 JL SHORT 002F7C87
002F7C7E 817F 34 C0000000 CMP DWORD PTR DS:[EDI+34],0C0 //сильванский кентавр
002F7C85 7C 34 JL SHORT 002F7CBB
т.е. бесстрашием обладают Лазурный дракон и диапазон существ от Верховного архангела (150) до командира Сопряжения (191).
Страх
002F7CEA 81FB 84000000 CMP EBX,84 //лазурный дракон
002F7CF0 74 75 JE SHORT 002F7D67
002F7CF2 81FB 99000000 CMP EBX,99 //антихрист
002F7CF8 74 6D JE SHORT 002F7D67
002F7CFA 81FB 9B000000 CMP EBX,9B //темный дракон
002F7D00 74 65 JE SHORT 002F7D67
002F7D16 813D 68218302 AE000000 CMP DWORD PTR DS:[2832168],0AE
002F7D20 7C 21 JL SHORT 002F7D43
002F7D22 813D 68218302 BF000000 CMP DWORD PTR DS:[2832168],0BF
002F7D2C 7F 15 JG SHORT 002F7D43
все командиры сопряжения (в качестве монстров видимо)
Магическое зеркало
00048528 8179 34 86000000 CMP DWORD PTR DS:[ECX+34],86
0004852F 75 1E JNZ SHORT 0004854F
где 86h = 134 - Сказочный дракон
Атака огненным шаром
0003F72C 83F8 2D CMP EAX,2D
0003F72F 0F85 EA020000 JNZ 0003FA1F
где 2Dh = 45 - Магог
Атака облаком смерти
002FF990 83F8 40 CMP EAX,40 //лич
002FF993 74 12 JE SHORT 002FF9A7
002FF995 83F8 41 CMP EAX,41 //могущественный лич
002FF998 74 0D JE SHORT 002FF9A7
002FF99A 3D C4000000 CMP EAX,0C4 //драколич
002FF99F 74 06 JE SHORT 002FF9A7
hippocamus
04 Jul 2008, 11:37
А Драколич разве облаком смерти стреляет? Какой-то зелёной гадостью вроде...
Облако смерти + иногда травит
Таблица существ, в которые трансформируются существа в преобразователе скелетов, начинается по адресу 0024130C - соответствено первое существо Копейщик. Для каждого существа отведено 4 байта. Заканчивается это по адресу 0024154С - тролль.
Затем продолжается по адресу 0031DA14 - катапульта, вплоть до адреса 0031DAE0 - драколич.
sergroj
07 Jul 2008, 13:48
24130C и 31DA14 - не постоянные адреса. На эти блоки где-то есть ссылки, при желании могу найти.
Чёртос-2 (Chortos-2)
28 Sep 2008, 16:05
Цитата(FakerNeo @ 31 Jul 2008, 16:35)
атака 44065C - таблица для монстров начиная с 16h монстра
защита 4412D8 - начиная с 3Fh монстра.
Цитата(major @ 31 Jul 2008, 17:20)
Только в 44065C находятся наложения заклинаний на монстров, а в 4412D8 - уникальные способности, как я понял.
По аналогии нашел таблицу, включающую WOG существ.
mem332AD8 - наложение заклов
mem332A4C - способности
Цитата(major @ 31 Jul 2008, 18:52)
mem332СС4 - таблица сопротивляемости магии существ начинается с гнома 10h
магические способности существ начинается с Архангела 0Dh почему то по трем адресам 332990, 3328D4 и 332818.
MasterOfPuppets
03 Feb 2010, 12:40
Заклинания, даваемые артефактами
По адресу mem004D95F2h находится указатель на case, содержащий 9 записей.
По адресу mem004D95EBh находится указатель на таблицу однобайтных данных, определяющих работу оператора. Таблица вмещает 49 значений, начиная с арта-86 и заканчивая артом-135.
Типы значений в таблице:
0 - дать все заклинания Огня
1 - дать все заклинания Воздуха
2 - дать все заклинания Воды
3 - дать все заклинания Земли
4 - дать заклинания "Вызвать Корабль" и "затопить Корабль"
5 - дать все заклинания 5-го уровня
6 - Дать "Армагеддон"
7 - Дать "Гром Титанов"
8 - ничего
341 - не соглашусь. Никаких ограничений нет! Ты неправильно понял код.
Добавлено ([mergetime]1265300645[/mergetime]):
Цитата(Master Of Puppets @ 03 Feb 2010, 12:40)
По адресу mem004D95E0h можно задать кол-во данных в таблице.
Не есть правильное утверждение
MasterOfPuppets
05 Feb 2010, 13:30
Неважно, как я понял код. Всё равно ничего мне это не дало, так как расширять case я не умею, а все стандартные значения мне на фиг не нужны.
Я просто поправил информацию, что ты предоставил, чтобы не дезинформировать общественность.
MasterOfPuppets
07 Feb 2010, 08:18
Спасибо, поправил.

Тут тоже поправь меня, если ошибаюсь.
Cнятие ограничений на показ диалога опыта армии:exe002B9F50h
exe002BF76Bh
exe002BFA89h - отвечает за показ диалога по улучшенному существу
exe002BFB15h - отвечает за показ диалога в окне вражеского стека
Есть ещё указатель на таблицу монстров со смещением, чтобы диалог нормально работал. Забыл, потом укажу.
Снятие ограничений для ERM-команд:exe002F1410h - MA при попытке получить значение
exe002EB4F8h - MA при попытке установить значение
exe002CDCA9h - UN:T
exe002CE326h - UN:G1
exe002CD4BDh - UN:A#/#/$.
exe002AFECAh - UN:A#/$
Таблица запрета/доступности артефактов на карте находится по адресу mem0456E2FCh.
Указатели, используемые ERM-командамиУказатель, смещение от начала таблицы монстров, команда.
mem7693397d 0 MA:O
mem7693514d +4 MA:L
mem7694533d +16 MA:X
mem7550016d +20 UN:G1/0
mem7550069d +24 UN:G1/1
mem7550123d +28 UN:G1/2
mem7693689d +32 MA:C (все)
mem7693743d +60 MA:F
mem7693797d +64 MA:I
mem7693851d +68 MA:G
mem7693905d +72 MA:R
mem7693959d +76 MA:P
mem7694013d +80 MA:S
mem7694099d +84 MA:A
mem7694154d +88 MA:D
mem7694209d +92 MA:M
mem7694264d +96 MA:E
mem7694319d +100 MA:N
mem7694374d +104 MA:B
mem7694429d +108 MA:V
mem7694484d +112 MA:H
mem7686722d - указатель на таблицу артефактов, отвечающий за работу вог-опции 902.
feanor
10 Feb 2010, 22:44
Код
CPU Disasm
0040EF33 BE 02000000 MOV ESI,2
mem:40EF44h - номер выкапываемого артефакта (Era1.6.exe, по идее - должно везде работать). В тех же местах можно поставить хуки на попытки копать.
Вытаскивайте ультимейты из двойки, господа
MasterOfPuppets
26 Feb 2010, 10:56
Открытие окна героя:
!!SN:E5118576/1/x1/x2;
x1 - номер героя
x2 - закрытие диалога при отпускании мыши: 0 - нет, 1 - да.
Case, управляющий кликами мыши на городских зданиях, находится по адресу 005D4EC0h, сразу за ним - таблица значений (005D4EF8h).
Парочка примеров, использующих функции этого оператора:
Вызов диалога Рынка:
!!SN:E6202336/1;
Возможен на глобальной карте, что полезнее, чем необходимость лезть всякий раз в экран города. Однако есть два мелких бага при таком использовании:
1. Если в экран города ни разу не заходили с запуска exe (не игры), будет вылет. Если же заходили, даже если рынка нет, диалог появится. При рестарте/запуске новой карты без перезапуска самой игры этого бага не будет.
2. Если у игрока нет ни одного Рынка, но он заходил в экран города, диалог выведется, но вылетит при попытке торговой операции.
Второй баг закономерен, и Рынки лучше посчитать, прежде чем решить, открывать ли диалог. А вот насчёт первого надо покопать...
Открытие диалога Торговцев Артефактами:
!!SN:E6201632/1;
Работает в любом городе, даже если здание 17 не построено. Если героя-гостя нет, выведется сообщение о запрете использования здания 17.
При определённых условиях можно открыть и даже использовать на глобальной карте, но лучше не надо, да и незачем.
CrackedMind
27 Feb 2010, 04:37
Создали бы давно уже какую нибудь вики и наполняли бы ее потихоньку. Было бы полезно я думаю некоторым товарищам
Berserker
27 Feb 2010, 15:21
Была вики. Посещение - 0, желание создавать и оформлять - 0. Так путь хоть на форуме.
feanor
28 Feb 2010, 21:44
Боевые машины, покупаемые в кузнях
6AAA60 - таблица боевых машин, покупаемых в Кузницах замков.
на каждую машину отводится по 4 байта, потом 4 байта - FF FF FF FF (итого - 8 байт.) Боевая машина, покупаемая в Ballista Yard, совпадает с БМ Замка, увы.
Added: 00642EA0 - таблица отображаемых в окне кузни существ.
tolich
28 Feb 2010, 21:48
Цитата(feanor @ 28 Feb 2010, 21:44)

Боевая машина, покупаемая в Ballista Yard, совпадает с БМ Замка, увы.
То есть, если Замку поставить телегу, то у варваров будет две?
feanor
28 Feb 2010, 21:59
00642EA0 - таблица отображаемых в окне кузни существ.
Цитата
То есть, если Замку поставить телегу, то у варваров будет две?
скорее варварам дадут купить БМ только в одном из строений, а в другом - всё, уже есть одна, не купить больше.
tolich
28 Feb 2010, 22:12
Я имел в виду, что в Кузне телега и на Дворе Баллист тоже телега... а не две телеги у одного героя.
MasterOfPuppets
07 Mar 2010, 11:07
Вызов Торгового Поста:
!!SN:E6202560/1;
feanor
18 Mar 2010, 21:17
5A0649 - switch для боевых заклинаний. Вроде как и анимация, и действительные эффекты.
4963C0 - ф-я показа анимации на поле боя. (нативный аналог !!BM:V). Принимает четыре параметра в стеке (хз что там с регистрами, вроде честный stdcall): первый - номер анимации в таблице, второй - указатель на некую неочевидную структуру, третий и четвертый - 0x64 и 0 почти всегда.
Через неё можно выйти на разные вещи типа срабатывания удачи (43F6F1), морали (464664 и 4648F0), страха (464В13) и тэпэ.
MasterOfPuppets
21 Mar 2010, 07:47
SUB_L004631E0 - функция, расставляющая существа (в частности, боевые машины) на поле боя. Проверка на наличие машин у героя, номера машин, их кол-во (которое, правда, в одном байте, но це можно исправить), позиция на поле боя - всё там.
laViper
25 Mar 2010, 19:38
То есть можно нормально поставть 10 балист и они будут мочить как 10 балист?
Etoprostoya
25 Mar 2010, 19:41
Цитата(laViper @ 25 Mar 2010, 19:38)
То есть можно нормально поставть 10 балист и они будут мочить как 10 балист?
"Поставить" - одна функция, а "мочить" - другая. Ты не путай и других не запутывай.
feanor
25 Mar 2010, 19:51
Структура заклинаний.
Указатель на таблицу заклинаний лежит в 687FA8. Адрес в нём динамический.
Описание.
struct
{
int null; //??
char *sound; //имя звука
int anim_id; //SS:X???
int flags; //флаги
char *name; //имя
int level;
int school;
int mana_cost[4];
int param_1;
int effects[4]; //SS:E
int city_freq[9]; //вероятности появления в городах
int ai_val[4]; //SS:I
char *desc[4]; //описания
}
Astaroth
26 Mar 2010, 15:56
Код
int null; //??
- Может это невозможность появления заклинания на карте? Но тогда было бы достаточно типа bool
feanor
26 Mar 2010, 15:58
Для этого есть другая таблица, емнип. У меня вчера было подозрение на SS:O, но проверять уже влом было
Etoprostoya
26 Mar 2010, 16:45
Цитата(Astaroth @ 26 Mar 2010, 15:56)
Код
int null; //??
- Может это невозможность появления заклинания на карте? Но тогда было бы достаточно типа bool
bool и есть int32. Как правило.
MasterOfPuppets
27 Mar 2010, 08:02
Цитата(Entuser @ 22 Jan 2008, 11:10)
7AD78 - тут в екзишнеке храниться число 5 - после загрузки изменяется на 34(HEX) - влияет на число загружаемых строк в ZCRTRAITS.
mem 007012A4 / file 29C2A4 - изменяет это значение и много других
Объяснение.
Файл с параметрами монстров был разбит разработчиками (видимо, для личного удобства) на разделы с промежутками в три строки, и грузится он пораздельно. Число 5 - это не что иное, как кол-во строк, грузящихся из последнего раздела текстовика (5 боевых машин). Соотвественно, ВОГ изменяет это значение на своё - 34h, что в exe по адресу 0x32532C.
С CrAnim-ом - абсолютно аналогично.
MasterOfPuppets
30 Mar 2010, 10:15
Шарпшутерство75DD50 cmp eax,00000095h
75DD55 jz L0075DDD2
75DD57 cmp eax,00000089h
75DD5C jz L0075DDD2
75DD5E cmp eax,000000AAh
75DD63 jz L0075DDD2
75DD65 cmp eax,000000ABh
75DD6A jz L0075DDD2
То есть, прямой стрелой пуляют 3 снайпера + Стрелковая Башня.
Нет пенальти за препятствия760590 cmp eax,00000022h
760593 jz L00760622
760599 cmp eax,00000023h
76059C jz L00760622
7605A2 cmp eax,00000088h
7605A7 jz L00760622
7605A9 cmp eax,00000089h
7605AE jz L00760622
7605B0 cmp eax,00000095h
7605B5 jz L00760622
7605B7 cmp eax,000000AAh
7605BC jz L00760622
7605BE cmp eax,000000ABh
7605C3 jz L00760622
То, что этот бонус даёт флаг 2048 - сказки.
feanor
11 Apr 2010, 21:17
Комбо-артефакты
Кажется, таблица комбо-артефактов расположена по адресу 788BF8. [00660B6C]
Формат хранения данных - что-то похожее на битовое поле, 18h байт на запись.
Размещаю изыскания
Master Of Puppets, по его же просьбе.
Ненависть 443138 mov dl,[eax+CASE_004434DC]
44313E jmp [CASE_PROCTABLE_004434C8+edx*4]
В маленькой (монстры 112-129) таблице 5 значений. Значения 00-03 чисто для элементалей - каждый элементаль ненавидит обоих элементалей противоположной стихии. Управление, однако, всё равно передаётся на PROC0004 - она же для остальных существ, т.е., там case вложен в case. Диапазон - от Ангела до Чёрного Дракона.
Содовский код там имеет вид:
CASE_004434C8_PROC0004:
443195 mov eax,[edi+34h]
443198 add ecx,FFFFFFF4h
44319B cmp ecx,00000047h
44319E ja CASE_004434F0_PROC0006
4431A4 xor edx,edx
4431A6 mov dl,[ecx+CASE_0044350C]
4431AC jmp [CASE_PROCTABLE_004434F0+edx*4]
Однако при запуске WoG код изменяется так:
CASE_004434C8_PROC0004:
443195 mov ecx,[ebp+08h]
443198 call SUB_L00766DE6
44319D or eax,eax
44319F jz L00443410
4431A5 mov ecx,[ebp-10h]
4431A8 jmp L00443211
4431AA nop
4431AB nop
Код меняет отрезок воговского копирования exe3273A4-3273AF (78BD8Ch/443195h/17h).
В итоге ненавистью существ в WoG занимается SUB_L00766E14, куда скопирован и case, и таблица СОДа. Туда же, видимо, встроена и ненависть через опыт существ.
При условии, что тип существа соответствует "ненавистному", задаётся процент доп. урона. В СОД это унифицировано, в ВОГ же - рутинно задаётся одной и той же командой:
mov dword ptr [ebp-0Ch],00000032h
Исключения - Титан и Чёрный Дракон. У них это:
mov dword ptr [ebp-0Ch],00000005h
Похоже на опечатку: вместо 150% урона - 105%. Несложный тест подтверждает, что баг реален и мы с ним жили.( Впрочем, у себя я его уже исправил.

Кстати, и в СОД, и в ВОГ Чёрный Дракон равнодушен к Гигантам. Справедливо - Титан тоже равнодушен к Красным.
Независимо от реальных процентов доп. урона, в логе битвы будет показано "50%". Проблема в упрощённом обращении к строке genrltxt.txt.
Кавалерийский бонус 75D823 cmp dword ptr [L028460C0],0000000Ah; - Каварелист
75D82A jnz L0075D838
75D82C mov dword ptr [L02846420],0000000Bh
75D836 jmp L0075D860
75D838 cmp dword ptr [L028460C0],0000000Bh; - Чемпион
75D83F jnz L0075D84D
75D841 mov dword ptr [L02846420],0000000Bh
Отсос 2-х очков маны 4650D0 sub eax,0000003Dh; - Привидение
..........
465174 add eax,FFFFFFFEh; - кол-во забираемых очков
Магический канал 5A24DC cmp dword ptr [eax-000000C0h],0000002Bh; - Чёрт
Смертельный удар 766DB9 sub eax,43; - Рыцарь Смерти
4435C0 jz L004435D1
............
4436DE cmp eax,00000014h; - шанс срабатывания абилки
Снижение стоимости заклинаний 766BFA cmp dword ptr [ebp-18h],00000022h - Маг
766BFE jz L00766C06
766C00 cmp dword ptr [ebp-18h],00000023h - АрхиМаг
766C04 jnz L00766C0D
766C06 mov dword ptr [ebp-0Ch],00000002h - кол-во очков на удешевление
Особые земли Case:
4FD5A1 mov cl,[eax+CASE_004FD5E8]
4FD5A7 jmp [CASE_PROCTABLE_004FD5D0+ecx*4]
Проверки для подсказок при наведении мыши, ПКМ и для !!TR:
4FD52A cmp eax,00000015h
4FD52D lea ecx,[edi+ecx*4]
4FD530 jz L004FD57F
4FD532 cmp eax,0000002Eh
4FD535 jz L004FD57F
4FD537 cmp eax,000000E3h
4FD53C jz L004FD57F
4FD53E cmp eax,000000E0h
4FD543 jz L004FD57F
4FD545 cmp eax,000000DEh
4FD54A jz L004FD57F
4FD54C cmp eax,000000E1h
4FD551 jz L004FD57F
4FD553 cmp eax,000000E4h
4FD558 jz L004FD57F
4FD55A cmp eax,000000E2h
4FD55F jz L004FD57F
4FD561 cmp eax,000000E7h
4FD566 jz L004FD57F
4FD568 cmp eax,000000E5h
4FD56D jz L004FD57F
Посмотреть журнал !!SN:E5433616/1;
Маленькое наблюдение.
Описанные тобой, МОР, свойства монстров,а именно: снижение стоимости заклинания, кавалерийский бонус, пенальти за расстояние и шарпшутерство - находятся почему-то в секции кода ЗВС? Тем не менее эти свойства есть и в оригинальном СОДе, может это промежуточный код?
feanor
16 Apr 2010, 21:53
Емнип, абилки вынесены в воговскую секцию для возможности относительно безгеморройно добавлять новых юнитов с этими свойствами. В соде-то все впритирку.
feanor
17 Apr 2010, 21:56
Привязка удачи к артефактам.К сожалению, это сделано в коде - нет никакой особой таблицы.
Функция проверки удачи - 0x4E3930.
Проверка на часы недоброго часа:
4E3966: 55h
4E39AB: 55h
Проверка на остальные артефакты:
4E3A52: C6h - брелок
4E3A90: 2Dh - глаз дракона
4E3ACD: 2Eh - клевер удачи
4E3B0B: 2Fh - карты
Пример кода на проверку одного артефакта:
Код
CPU Disasm
Address Hex dump Command Comments
004E3A8C |. 8BCF MOV ECX,EDI
004E3A8E |> 8339 2D /CMP DWORD PTR DS:[ECX],2D //номер артефакта
004E3A91 |. 74 31 |JE SHORT 004E3AC4
004E3A93 |. 40 |INC EAX
004E3A94 |. 83C1 08 |ADD ECX,8
004E3A97 |. 83F8 13 |CMP EAX,13
004E3A9A |.^ 7C F2 \JL SHORT 004E3A8E
004E3A9C |. 8B0D 680B6600 MOV ECX,DWORD PTR DS:[660B68]
004E3AA2 |. 8B81 B8050000 MOV EAX,DWORD PTR DS:[ECX+5B8]
004E3AA8 |. 83F8 FF CMP EAX,-1
004E3AAB |. 74 1A JE SHORT 004E3AC7
004E3AAD |. 8D1440 LEA EDX,[EAX*2+EAX]
004E3AB0 |. A1 6C0B6600 MOV EAX,DWORD PTR DS:[660B6C]
004E3AB5 |. 8B0CD0 MOV ECX,DWORD PTR DS:[EDX*8+EAX]
004E3AB8 |. 51 PUSH ECX ; /Arg1
004E3AB9 |. 8BCE MOV ECX,ESI ; |
004E3ABB |. E8 A059FFFF CALL 004D9460 ; \Era_1_6.004D9460 - функция проверки наличия артефакта
004E3AC0 |. 84C0 TEST AL,AL
004E3AC2 |. 74 03 JE SHORT 004E3AC7
004E3AC4 |> FF45 0C INC DWORD PTR SS:[ARG.2] //увеличение удачи
Аналогичная функция для морали - 004E3C20