Объявления

Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

Энциклопедия алгоритмов HoMM 3

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 07 авг 2019, 05:21

Код для запрещения соединений зон через телепортеры/обычные сухопутные пути
(из мода Heroes 3 Plus)

Код: Выделить всё
int __stdcall getTemplateConnections(LoHook* h, HookContext* c)
{
   _RMGTemplate_* Template1 = (_RMGTemplate_*)c->edx;
   NZones = ((int)Template1->zones.EndData - (int)Template1->zones.Data) / 4;

    return EXEC_DEFAULT;
}

int __stdcall disableRp(LoHook* h, HookContext* c)
{
   _RMGStruct_* RmgStruct;
   _RMGGenZone_* genZone;
   _ZoneConnection_* connection;
   RmgStruct = (_RMGStruct_*)c->esi;
   genZone = (_RMGGenZone_*)c->ebx;
   connection = (_ZoneConnection_*)c->edi;

   _RMGGenZone_* genZone2 = 0;
   if(connection->another_zone_settings->id < NZones)
      genZone2 = RmgStruct->RMGGenZones[connection->another_zone_settings->id];
   if(genZone2 !=0 && RmgStruct->WaterAmount > 1)
   if(genZone->z == 0 && genZone2->z == 0)
   //if(genZone->ZoneInfo->type == 2 || connection->another_zone_settings->type == 2)
   {
      c->return_address = 0x543A8A;
      return NO_EXEC_DEFAULT;
   }

   return EXEC_DEFAULT;
}

int __stdcall disableTeleports(LoHook* h, HookContext* c)
{
   _RMGStruct_* RmgStruct;
   _RMGGenZone_* genZone;
   _ZoneConnection_* connection;
   RmgStruct = (_RMGStruct_*)c->esi;
   genZone = (_RMGGenZone_*)c->ecx;
   connection = (_ZoneConnection_*)c->ebx;

   _RMGGenZone_* genZone2 = 0;
   if(connection->another_zone_settings->id < NZones)
      genZone2 = RmgStruct->RMGGenZones[connection->another_zone_settings->id];
   if(genZone2 != 0 && RmgStruct->WaterAmount > 1)
   if(genZone->z == 0 && genZone2->z == 0)
   //if(genZone->ZoneInfo->type == 2 || connection->another_zone_settings->type == 2)
   {
      return NO_EXEC_DEFAULT;
   }
   

   return EXEC_DEFAULT;
}

...
_PI->WriteLoHook(0x549EA4, getTemplateConnections);
_PI->WriteLoHook(0x543E06, disableTeleports);
_PI->WriteLoHook(0x543A40, disableRp);

Вернуться к началу

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Catastrophe » 07 авг 2019, 07:23

Ben80 писал(а):

_Player_*
field_30[4]

Содержит тип ИИ (Воин, Строитель, Исследователь).

0 - случайный, 1 - воин, 2 - строитель, 3 - исследователь?
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 02 май 2020, 05:36

Полная структура флагов для заклинаний:

Код: Выделить всё
    struct SpellFlags
    {
        unsigned bf : 1;                    // 1
        unsigned adv : 1;                   // 2
        unsigned have_duration : 1;         // 4
        unsigned creature : 1;              // 8
        unsigned single_target : 1;         // 10
        unsigned shooter_target : 1;        // 20
        unsigned expert_mass_version : 1;   // 40
        unsigned target_anywhere : 1;       // 80
        unsigned change_bf : 1;             // 100
        unsigned damaging : 1;              // 200
        unsigned mind : 1;                  // 400
        unsigned buff : 1;                  // 800
        unsigned siege_weapon_disabled : 1; // 1000
        unsigned from_artifact : 1;         // 2000
        unsigned defending : 1;             // 4000   
        unsigned AI_usual_damage : 1;       // 8000
        unsigned AI_inferno_chainL : 1;     // 10000
        unsigned AI_mass_damage : 1;        // 20000
        unsigned AI_buff_debuff : 1;        // 40000
        unsigned AI_resur_hypn_summon : 1;  // 80000
        unsigned AI_misc : 1;               // 100000
        unsigned _unused : 11   ;           // 200000       
    }flags;
   
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 25 май 2021, 07:20

Структуры для битв-симуляций ИИ. Есть уточнения по сравнению с H3API.

Для войска:
Код: Выделить всё
struct _AI_SimulationBattle_Side_
{
 _List_<_AISimulationCreature_> creature; // +0;
 int specialTerrain; // +16
 int spellPoints; // +20
 _bool_ canCastSpells; // +24
 int armyStrength; // +28
 _bool_ tactics; // +32
 _Hero_* hero; // + 36
 _Army_* army; // +40
 _Hero_* heroEnemy; // +44
 _byte_ isRestrictedMovement; // +48
 _byte_ unk_1; // +49
 _word_ restrictionLevel; // +50
};


Для каждого отряда:
Код: Выделить всё
struct _AISimulationCreature_
{
 int stackIndex; // 0
 int type; // 4
 int count; // 8
 int count_initial; // 12 используется при касте Resurrect ??
 int speed; // 16
 _byte_ unk_1[4]; // 20
 double meleePowerCoef; // 24
 double unkPowerCoef; // 32 не используется ??
 double archeryPowerCoef; // 40
 double power_per_hp; // 48 используется при касте заклинаний
 int turnsToEnemy; // 56
 int creaturePower; // 60
 int stackPower; // 64
 _byte_ unk_2[4]; // 68
};

Последний раз редактировалось Ben80 29 май 2021, 11:10, всего редактировалось 2 раз(а).
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение void_17 » 04 июн 2021, 13:05

Это не алгоритм героев 3, а просто заголовочный файл, однако не могу не прикрепить его сюда. Это будет полезно многим
Здесь определения из IDA.

Код: Выделить всё
#pragma once
#if defined(__GNUC__)
  typedef          long long ll;
  typedef unsigned long long ull;
  #define __int64 long long
  #define __int32 int
  #define __int16 short
  #define __int8  char
  #define MAKELL(num) num ## LL
  #define FMT_64 "ll"
#elif defined(_MSC_VER)
  typedef          __int64 ll;
  typedef unsigned __int64 ull;
  #define MAKELL(num) num ## i64
  #define FMT_64 "I64"
#elif defined (__BORLANDC__)
  typedef          __int64 ll;
  typedef unsigned __int64 ull;
  #define MAKELL(num) num ## i64
  #define FMT_64 "L"
#else
  #error "unknown compiler"
#endif
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned short ushort;
//typedef unsigned long ulong;

typedef          char   int8;
typedef   signed char   sint8;
typedef unsigned char   uint8;
typedef          short  int16;
typedef   signed short  sint16;
typedef unsigned short  uint16;
typedef          int    int32;
typedef   signed int    sint32;
typedef unsigned int    uint32;
typedef ll              int64;
typedef ll              sint64;
typedef ull             uint64;

// Partially defined types:
#define _BYTE  uint8
#define _WORD  uint16
#define _DWORD uint32
#define _QWORD uint64
#if !defined(_MSC_VER)
#define _LONGLONG __int128
#endif

#ifndef _WINDOWS_
typedef int8 BYTE;
typedef int16 WORD;
typedef int32 DWORD;
typedef int32 LONG;
#endif
typedef int64 QWORD;
#ifndef __cplusplus
typedef int bool;       // we want to use bool in our C programs
#endif

// Some convenience macros to make partial accesses nicer
// first unsigned macros:
#define LOBYTE(x)   (*((_BYTE*)&(x)))   // low byte
#define LOWORD(x)   (*((_WORD*)&(x)))   // low word
#define LODWORD(x)  (*((_DWORD*)&(x)))  // low dword
#define HIBYTE(x)   (*((_BYTE*)&(x)+1))
#define HIWORD(x)   (*((_WORD*)&(x)+1))
#define HIDWORD(x)  (*((_DWORD*)&(x)+1))
#define BYTEn(x, n)   (*((_BYTE*)&(x)+n))
#define WORDn(x, n)   (*((_WORD*)&(x)+n))
#define BYTE1(x)   BYTEn(x,  1)         // byte 1 (counting from 0)
#define BYTE2(x)   BYTEn(x,  2)
#define BYTE3(x)   BYTEn(x,  3)
#define BYTE4(x)   BYTEn(x,  4)
#define BYTE5(x)   BYTEn(x,  5)
#define BYTE6(x)   BYTEn(x,  6)
#define BYTE7(x)   BYTEn(x,  7)
#define BYTE8(x)   BYTEn(x,  8)
#define BYTE9(x)   BYTEn(x,  9)
#define BYTE10(x)  BYTEn(x, 10)
#define BYTE11(x)  BYTEn(x, 11)
#define BYTE12(x)  BYTEn(x, 12)
#define BYTE13(x)  BYTEn(x, 13)
#define BYTE14(x)  BYTEn(x, 14)
#define BYTE15(x)  BYTEn(x, 15)
#define WORD1(x)   WORDn(x,  1)
#define WORD2(x)   WORDn(x,  2)         // third word of the object, unsigned
#define WORD3(x)   WORDn(x,  3)
#define WORD4(x)   WORDn(x,  4)
#define WORD5(x)   WORDn(x,  5)
#define WORD6(x)   WORDn(x,  6)
#define WORD7(x)   WORDn(x,  7)

// now signed macros (the same but with sign extension)
#define SLOBYTE(x)   (*((int8*)&(x)))
#define SLOWORD(x)   (*((int16*)&(x)))
#define SLODWORD(x)  (*((int32*)&(x)))
#define SHIBYTE(x)   (*((int8*)&(x)+1))
#define SHIWORD(x)   (*((int16*)&(x)+1))
#define SHIDWORD(x)  (*((int32*)&(x)+1))
#define SBYTEn(x, n)   (*((int8*)&(x)+n))
#define SWORDn(x, n)   (*((int16*)&(x)+n))
#define SBYTE1(x)   SBYTEn(x,  1)
#define SBYTE2(x)   SBYTEn(x,  2)
#define SBYTE3(x)   SBYTEn(x,  3)
#define SBYTE4(x)   SBYTEn(x,  4)
#define SBYTE5(x)   SBYTEn(x,  5)
#define SBYTE6(x)   SBYTEn(x,  6)
#define SBYTE7(x)   SBYTEn(x,  7)
#define SBYTE8(x)   SBYTEn(x,  8)
#define SBYTE9(x)   SBYTEn(x,  9)
#define SBYTE10(x)  SBYTEn(x, 10)
#define SBYTE11(x)  SBYTEn(x, 11)
#define SBYTE12(x)  SBYTEn(x, 12)
#define SBYTE13(x)  SBYTEn(x, 13)
#define SBYTE14(x)  SBYTEn(x, 14)
#define SBYTE15(x)  SBYTEn(x, 15)
#define SWORD1(x)   SWORDn(x,  1)
#define SWORD2(x)   SWORDn(x,  2)
#define SWORD3(x)   SWORDn(x,  3)
#define SWORD4(x)   SWORDn(x,  4)
#define SWORD5(x)   SWORDn(x,  5)
#define SWORD6(x)   SWORDn(x,  6)
#define SWORD7(x)   SWORDn(x,  7)


// Helper functions to represent some assembly instructions.

#ifdef __cplusplus

// Fill memory block with an integer value
inline void memset32(void *ptr, uint32 value, int count)
{
  uint32 *p = (uint32 *)ptr;
  for ( int i=0; i < count; i++ )
    *p++ = value;
}

// Generate a reference to pair of operands
template<class T>  int16 __PAIR__( int8  high, T low) { return ((( int16)high) << sizeof(high)*8) | uint8(low); }
template<class T>  int32 __PAIR__( int16 high, T low) { return ((( int32)high) << sizeof(high)*8) | uint16(low); }
template<class T>  int64 __PAIR__( int32 high, T low) { return ((( int64)high) << sizeof(high)*8) | uint32(low); }
template<class T> uint16 __PAIR__(uint8  high, T low) { return (((uint16)high) << sizeof(high)*8) | uint8(low); }
template<class T> uint32 __PAIR__(uint16 high, T low) { return (((uint32)high) << sizeof(high)*8) | uint16(low); }
template<class T> uint64 __PAIR__(uint32 high, T low) { return (((uint64)high) << sizeof(high)*8) | uint32(low); }

// rotate left
template<class T> T __ROL__(T value, uint count)
{
  const uint nbits = sizeof(T) * 8;
  count %= nbits;

  T high = value >> (nbits - count);
  value <<= count;
  value |= high;
  return value;
}

// rotate right
template<class T> T __ROR__(T value, uint count)
{
  const uint nbits = sizeof(T) * 8;
  count %= nbits;

  T low = value << (nbits - count);
  value >>= count;
  value |= low;
  return value;
}

// carry flag of left shift
template<class T> int8 __MKCSHL__(T value, uint count)
{
  const uint nbits = sizeof(T) * 8;
  count %= nbits;

  return (value >> (nbits-count)) & 1;
}

// carry flag of right shift
template<class T> int8 __MKCSHR__(T value, uint count)
{
  return (value >> (count-1)) & 1;
}

// sign flag
template<class T> int8 __SETS__(T x)
{
  if ( sizeof(T) == 1 )
    return int8(x) < 0;
  if ( sizeof(T) == 2 )
    return int16(x) < 0;
  if ( sizeof(T) == 4 )
    return int32(x) < 0;
  return int64(x) < 0;
}

// overflow flag of subtraction (x-y)
template<class T, class U> int8 __OFSUB__(T x, U y)
{
  if ( sizeof(T) < sizeof(U) )
  {
    U x2 = x;
    int8 sx = __SETS__(x2);
    return (sx ^ __SETS__(y)) & (sx ^ __SETS__(x2-y));
  }
  else
  {
    T y2 = y;
    int8 sx = __SETS__(x);
    return (sx ^ __SETS__(y2)) & (sx ^ __SETS__(x-y2));
  }
}

// overflow flag of addition (x+y)
template<class T, class U> int8 __OFADD__(T x, U y)
{
  if ( sizeof(T) < sizeof(U) )
  {
    U x2 = x;
    int8 sx = __SETS__(x2);
    return ((1 ^ sx) ^ __SETS__(y)) & (sx ^ __SETS__(x2+y));
  }
  else
  {
    T y2 = y;
    int8 sx = __SETS__(x);
    return ((1 ^ sx) ^ __SETS__(y2)) & (sx ^ __SETS__(x+y2));
  }
}

// carry flag of subtraction (x-y)
template<class T, class U> int8 __CFSUB__(T x, U y)
{
  int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);
  if ( size == 1 )
    return uint8(x) < uint8(y);
  if ( size == 2 )
    return uint16(x) < uint16(y);
  if ( size == 4 )
    return uint32(x) < uint32(y);
  return uint64(x) < uint64(y);
}

// carry flag of addition (x+y)
template<class T, class U> int8 __CFADD__(T x, U y)
{
  int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U);
  if ( size == 1 )
    return uint8(x) > uint8(x+y);
  if ( size == 2 )
    return uint16(x) > uint16(x+y);
  if ( size == 4 )
    return uint32(x) > uint32(x+y);
  return uint64(x) > uint64(x+y);
}

#else
// The following definition is not quite correct because it always returns
// uint64. The above C++ functions are good, though.
#define __PAIR__(high, low) (((uint64)(high)<<sizeof(high)*8) | low)
// For C, we just provide macros, they are not quite correct.
#define __ROL__(x, y) __rotl__(x, y)      // Rotate left
#define __ROR__(x, y) __rotr__(x, y)      // Rotate right
#define __CFSHL__(x, y) invalid_operation // Generate carry flag for (x<<y)
#define __CFSHR__(x, y) invalid_operation // Generate carry flag for (x>>y)
#define __CFADD__(x, y) invalid_operation // Generate carry flag for (x+y)
#define __CFSUB__(x, y) invalid_operation // Generate carry flag for (x-y)
#define __OFADD__(x, y) invalid_operation // Generate overflow flag for (x+y)
#define __OFSUB__(x, y) invalid_operation // Generate overflow flag for (x-y)
#endif

// No definition for rcl/rcr because the carry flag is unknown
#define __RCL__(x, y)    invalid_operation // Rotate left thru carry
#define __RCR__(x, y)    invalid_operation // Rotate right thru carry
#define __MKCRCL__(x, y) invalid_operation // Generate carry flag for a RCL
#define __MKCRCR__(x, y) invalid_operation // Generate carry flag for a RCR
#define __SETP__(x, y)   invalid_operation // Generate parity flag for (x-y)

// In the decompilation listing there are some objects declarared as _UNKNOWN
// because we could not determine their types. Since the C compiler does not
// accept void item declarations, we replace them by anything of our choice,
// for example a char:

#define _UNKNOWN char

#ifdef _MSC_VER
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif
Вернуться к началу

offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение RoseKavalier » 17 июл 2021, 01:02

In case anyone missed it, XEPOMAHT stumbled on some symbols for Restoration of Erathia:
Source file names
Variable values (1/2)
Variable values (2/2)

There are also a large number of class and method names available, however I don't know how to decompile DreamCastcode ("Sorry, the current file is not decompilable").
Ghidra can decompile it but it's not picking up symbols for me.
Изображение

Some interesting names and their H3API counterpart:

Код: Выделить всё
H3Main ... game
H3Hero ... hero
H3AdventureManager ... advManager
H3Position ... type_point (this smells like Gus Smedstad)
H3LoadedDef ... CSprite
H3TextTable ... TSpreadsheetResource
H3DlgItem ... widget
H3DlgPcx ... bitmapBorder
H3DlgPcx16 ... bitmapBorder16
H3DlgDefButton ... button
H3BaseDlg ... heroWindow
H3DlgDef ... iconWidget
H3MainSetup ... NewfullMap
H3MapItem ... NewmapCell
H3ObjectDraw ... NewmapCell::TObjectCell
H3Pathfinder ... searchArray (this also appears in Heroes 2)
H3CombatCreature ... army (same as Heroes 2)
H3Army ... armyGroup (same as Heroes 2)
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение AlexSpl » 17 июл 2021, 13:46

Так собрали версию для Dreamcast или нет? Я новостей об этом нигде не встречал. Ссылки на образ удалены файлообменниками, кстати. Так понимаю, это была играбельная версия? Какие-то скрины видел очень давно, но всегда считал, что версию для Dreamcast так и не доделали.

2RoseKavalier: Поддержка sh3/3b, sh4 (Dreamcast)/4b доступна в расширенной поставке IDA Pro. Пробовали выбирать тип процессора Renesas SH-4? Если не сложно, поделитесь, пожалуйста, исполняемым файлом. Попробую поковырять.
Вернуться к началу

offlineАватара пользователя
Roman2211  
Подмастерье
Подмастерье
 
Сообщения: 133
Зарегистрирован: 03 сен 2014, 11:39
Пол: Не указан
Награды: 1
Высшая медаль (1)
Поблагодарили: 69 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Roman2211 » 17 июл 2021, 17:30

Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение AlexSpl » 17 июл 2021, 18:21

Mega был отличным файлообменником, как когда-то Rapidshare, а теперь скатился. Помню, что-то качал, а посередине скачивания - бац - сообщение: "превышен какой-то там лимит". Здесь обращение-матерное слово, а сразу предупредить нельзя было? Короче, теперь Mega очень сильно не уважаю.
Вернуться к началу

offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение RoseKavalier » 17 июл 2021, 19:32

Working Image Link

The Dreamcast version was worked on for quite a while (you can see some videos on youtube) and had some funny quirks to get around some limitations (most interface redrawn, combat screen would scroll since not wide enough)... eventually they abandoned the port because the Dreamcast was not powerful enough. There's more information available if you search for it, one of the developers working on it made an interesting post with more details like this.

@AlexSpl
Yep, it defaulted to Renesas SH-4 (little endian), I tried the others but same result.
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4