Объявления
Поздравляем
Roman2211


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

База данных IDA от void17

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

Re: База данных IDA от void17

Сообщение void_17 » 25 ноя 2021, 11:38

Не, всмысле совместно работать над базой будем. Вы будете, допустм, функции разбирать, я в другое время буду заниматься переносом сигнатур и названий типов и т.д.
Вместе над одной базой работать эффективнее, чем мне в одиночку сигнатуры переносить и по отдельности обмениваться базами.

В changelog файлике будем писать, кто последний раз заходил и что нового в базу внес.
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 25 ноя 2021, 12:13

Я прекрасно понимаю все преимущества совместной работы, даже если она не ведётся параллельно, но работать на своём компе всё-таки удобнее и привычнее.
Вернуться к началу

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

Re: База данных IDA от void17

Сообщение void_17 » 25 ноя 2021, 12:18

Прикол в чем: вы можете между компами копировать данные. Я поступать буду так: копировать на свой комп, на своем компе работать, обновлять базу на гугл диске, затем копировать на сервер и записывать в ченджлог.
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 25 ноя 2021, 12:26

Ну, можно, конечно, заходить и проверять, не работает ли над базой кто-то. Копировать её себе и писать, что база занята до конца следующей недели :smile1: Шучу, конечно, но я, например, могу поработать полчасика и оставить базу открытой, потом вернуться. А при совместной работе придётся каждый раз заливать промежуточную работу и ставить в известность, что база освободилась. Можно попробовать, но это точно будет неудобно. Я могу занять базу на весь день, а у кого-то настроение поработать и т.п.

* * *
Аргументы std::vector<army*>* armyVector можно задавать как std::vector* armyVector, а потом уже в коде менять тип First и Last на army*.

* * *
И всё-таки она вертится умеет делить нацело на 3!

Код: Выделить всё
int __thiscall type_AI_spellcaster::get_age_value(type_AI_spellcaster *this, const army *stack, type_enchant_data data)
{
  if ( this->DestroyedOrWarMachine )
    return 0;
  else
    return army::get_total_combat_value(stack, this->attack, this->defense) / 3;
}

Просто аргументы нужно было правильно прописать. В базе много где с аргументами беда.
Вернуться к началу

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

Re: База данных IDA от void17

Сообщение void_17 » 25 ноя 2021, 13:50

Цитата:
Просто аргументы нужно было правильно прописать. В базе много где с аргументами беда.

В 90% рекоммендую аргументы сверять с сигнатурой из Dreamcast базы.
Вернуться к началу

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

Re: База данных IDA от void17

Сообщение void_17 » 25 ноя 2021, 13:52

Как закончите работу сегодня, скопируйте базу на сервер, хорошо?
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 25 ноя 2021, 16:11

Сегодня-завтра постараюсь закончить разбор класса type_AI_spellcaster, чтобы хоть какой-то результат был, и залью. Но я считаю, что гораздо удобнее работать через координатора, который будет вносить изменения. Так можно продолжать работать над базой когда угодно.

Как бороться с таким вот:

Код: Выделить всё
Monster = &CombatManager->Army[0][14 * side + 7 * side + v10];

14 + 7 = 21, так что это сторона, т.е. это &CombatManager->Army[side][v10], но реально ли привести к такому виду?

Компилятор сходит с ума :smile4:

Код: Выделить всё
int __thiscall combatManager::get_total_combat_value(
        combatManager *this,
        int side,
        int attack,
        int defense,
        bool IncludeImmobileStacks)
{
  int _9_side_; // eax
  int total_combat_value; // ecx
  army *iStack; // esi
  ECreatureType CreatureType; // eax
  int Sum; // [esp+Ch] [ebp-4h]
  int stacksNum; // [esp+18h] [ebp+8h]

  _9_side_ = 9 * side;
  total_combat_value = 0;
  Sum = 0;
  stacksNum = 0;
  // Компилятор сходит с ума:
  // 24 * (32 * (side + 36 * side) - side) =
  // 24 * (32 * side + 1152 * side - side) =
  // 24 * 1183 * side = 28392 * side =
  // 1352 * 21 * side = sizeof(army) * 21 * side,
  // так что это обычный цикл по всем отрядам стороны side
  for ( iStack = (this->Army[0] + 24 * (32 * (side + 4 * _9_side_) - side)); stacksNum < this->ArmyNum[side]; ++stacksNum )
  {
    if ( (iStack->Flags & CF_IMMOBILE) == 0 )
    {
      CreatureType = iStack->CreatureType;
      if ( CreatureType != CID_ARROW_TOWER
        && (IncludeImmobileStacks
         || !iStack->SpellDuration[SPL_BLIND]
         && !iStack->SpellDuration[SPL_STONE_GAZE]
         && !iStack->SpellDuration[SPL_PARALYZE]
         && CreatureType != CID_FIRST_AID_TENT
         && CreatureType != CID_AMMO_CART) )
      {
        total_combat_value = army::get_total_combat_value(iStack, attack, defense) + Sum;
        Sum = total_combat_value;
      }
    }
    ++iStack;
  }
  return total_combat_value;
}
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 25 ноя 2021, 19:11

Рейтинги опасности в type_AI_combat_parameters:

Код: Выделить всё
type_AI_combat_parameters *__thiscall type_AI_combat_parameters::type_AI_combat_parameters(
        type_AI_combat_parameters *this,
        combatManager *pCombatManager,
        int side)
{
  int *ArmyNum; // eax
  combatManager *pCombatManager_0; // ebx
  army *iArmy; // edi
  int defense_modifier; // eax
  int attack_modifier; // ebx
  bool Done; // zf
  int total_combat_value_2; // eax
  int total_combat_value; // eax
  int attack_modifier_0; // ecx
  int casterSide; // edx
  int total_combat_value_0; // eax
  int attack_modifier_1; // ecx
  int enemySide; // edx
  int total_combat_value_1; // eax
  int attack_modifier_2; // ecx
  int enemySide_0; // edx
  int enemyTotalCombatValue; // edx
  int casterTotalCombatValueDoubled; // ecx
  int casterActiveStacksCombatValue; // ecx
  int i; // ecx
  bool can_shoot; // [esp+10h] [ebp-18h]
  int iSide; // [esp+18h] [ebp-10h]
  army (*Army)[21]; // [esp+1Ch] [ebp-Ch]
  int *ArmyNum_0; // [esp+20h] [ebp-8h]
  char v29; // [esp+27h] [ebp-1h]
  combatManager *casterActiveStacksCombatValue_0; // [esp+30h] [ebp+8h]
  int iStack; // [esp+34h] [ebp+Ch]
  int total_combat_value_3; // [esp+34h] [ebp+Ch]

  pCombatManager_0 = pCombatManager;
  iArmy = pCombatManager->Army[0];
  this->side[AI_CASTER] = side;
  ArmyNum = pCombatManager->ArmyNum;
  v29 = 1;
  this->side[1] = 1 - side;
  this->attack_modifier = 0;
  this->defense_modifier = 0;
  this->isOpponentDangerous = 0;
  this->field_9 = 0;
  Army = pCombatManager->Army;
  ArmyNum_0 = pCombatManager->ArmyNum;
  iSide = 2;
  do
  {
    for ( iStack = 0; iStack < *ArmyNum; ++iStack )
    {
      if ( iArmy->AmountAlive > 0 && iArmy->CreatureType != CID_ARROW_TOWER )
      {
        can_shoot = army::can_shoot(iArmy, 0);
        attack_modifier = army::get_attack_modifier(iArmy, 0, can_shoot);
        defense_modifier = army::get_defense_modifier(iArmy);
        if ( (v29 || this->attack_modifier > attack_modifier) && (this->attack_modifier = attack_modifier, v29)
          || this->defense_modifier > defense_modifier )
        {
          this->defense_modifier = defense_modifier;
        }
        pCombatManager_0 = pCombatManager;
        ArmyNum = ArmyNum_0;
        v29 = 0;
      }
      ++iArmy;
    }
    ++ArmyNum;
    // Переходим к следующей стороне
    iArmy = &(*Army)[21];
    Done = iSide == 1;
    ArmyNum_0 = ArmyNum;
    ++Army;
    --iSide;
  }
  while ( !Done );
  total_combat_value = combatManager::get_total_combat_value(
                         pCombatManager_0,
                         this->side[AI_CASTER],
                         this->attack_modifier,
                         this->defense_modifier,
                         1);
  attack_modifier_0 = this->attack_modifier;
  casterSide = this->side[AI_CASTER];
  this->casterTotalCombatValue = total_combat_value;
  total_combat_value_0 = combatManager::get_total_combat_value(
                           pCombatManager_0,
                           casterSide,
                           attack_modifier_0,
                           this->defense_modifier,
                           0);
  attack_modifier_1 = this->attack_modifier;
  enemySide = this->side[AI_ENEMY];
  this->casterActiveStacksCombatValue = total_combat_value_0;
  total_combat_value_1 = combatManager::get_total_combat_value(
                           pCombatManager_0,
                           enemySide,
                           attack_modifier_1,
                           this->defense_modifier,
                           1);
  attack_modifier_2 = this->attack_modifier;
  enemySide_0 = this->side[AI_ENEMY];
  this->enemyTotalCombatValue = total_combat_value_1;
  total_combat_value_2 = combatManager::get_total_combat_value(
                           pCombatManager_0,
                           enemySide_0,
                           attack_modifier_2,
                           this->defense_modifier,
                           0);
  enemyTotalCombatValue = this->enemyTotalCombatValue;
  casterTotalCombatValueDoubled = 2 * this->casterTotalCombatValue;
  this->enemyActiveStacksCombatValue = total_combat_value_2;
  if ( casterTotalCombatValueDoubled < enemyTotalCombatValue
    && (gpGame->PlayerInfo.GameDifficulty > EASY || gpCombatManager->isHuman[this->side[AI_CASTER]]) )
  {
    this->isOpponentDangerous = 1;
  }
  total_combat_value_3 = total_combat_value_2;
  casterActiveStacksCombatValue = this->casterActiveStacksCombatValue;
  casterActiveStacksCombatValue_0 = casterActiveStacksCombatValue;
  // Выбираем сильнейшую сторону
  if ( casterActiveStacksCombatValue < total_combat_value_2 )
  {
    casterActiveStacksCombatValue = total_combat_value_2;
    total_combat_value_2 = this->casterActiveStacksCombatValue;
    casterActiveStacksCombatValue_0 = casterActiveStacksCombatValue;
    total_combat_value_3 = total_combat_value_2;
  }
  // Определяем уровень опасности по отношению активных сил армий
  if ( 5 * total_combat_value_2 > casterActiveStacksCombatValue && casterActiveStacksCombatValue )
  {
    this->DangerRating = 0;
    do
    {
      i = this->DangerRating;
      // Рейтинги опасности:
      // DangerRating = 1 при отношении сил более 2.6
      // DangerRating = 2 при отношении сил более 1.9
      // DangerRating = 3 при отношении сил более 1.5
      // DangerRating = 4 при отношении сил более 1.31
      // DangerRating = 5 при отношении сил более 1.2
      // DangerRating = 6 при отношении сил более 1.13
      if ( casterActiveStacksCombatValue_0 / total_combat_value_3 >= StrengthRatio[i] )
        break;
      this->DangerRating = i + 1;
    }
    while ( i + 1 < 6 );
    // Мининальный рейтинг опасности - 1
    ++this->DangerRating;
    return this;
  }
  else
  {
    this->DangerRating = 1;
    return this;
  }
}

Только пока не выяснял, для чего они. Может, для принятия решения о побеге (но тогда что они делают в type_AI_combat_parameters?). Может, влияют на поведение компа при касте заклинаний. Например, я замечал, что комп под конец, если побеждает с большим отрывом, кастует Resurrection, а если проигрывает, спамит призывом. Но это нужно проверять, а из-за этих повторных использований одних и тех же переменных, не сразу поймёшь, о какой стороне идёт речь, даже в декомпилированном листинге. Нужно упрощать код в блокноте :smile1: Но это уже позже.

Итого, type_AI_combat_parameters выглядит вот так:

Код: Выделить всё
type_AI_combat_parameters struc ; (sizeof=0x28, align=0x4, mappedto_370)
00000000                                                             ; XREF: FF015A1C/r
00000000 attack_modifier dd ?
00000004 defense_modifier dd ?
00000008 isOpponentDangerous db ?
00000009 field_9   db ?                                              ; XREF: long combatManager::choose_melee_action(army *,bool,bool,long)+1F/w
0000000A field_A   db ?
0000000B field_B   db ?
0000000C casterTotalCombatValue dd ?
00000010 enemyTotalCombatValue dd ?
00000014 casterActiveStacksCombatValue dd ?
00000018 enemyActiveStacksCombatValue dd ?
0000001C DangerRating dd ?
00000020 side      dd 2 dup(?)
00000028 type_AI_combat_parameters ends

Нераспознанное поле field_9 (предполагаю, что это флаг симуляции битвы isBattleSimulated, например), остальные, скорее всего, паддинг (align = 4).

Чтобы окончательно разобраться, нужно эти поля визуализировать и посмотреть, как они меняются в реальном бою. Можно хукнуть type_AI_combat_parameters::type_AI_combat_parameters() и выводить сообщения, например.
Вернуться к началу

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

Re: База данных IDA от void17

Сообщение void_17 » 26 ноя 2021, 02:28

И выводить перед каждым боем? Надо попробовать
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 26 ноя 2021, 10:38

На сервер захожу, просит сменить пароль и дальше не пускает, поэтому просто залью на файлообменник.

https://dropmefiles.com/NGX0g

Названия полей, разумеется, не окончательные, а некоторые, возможно, и вовсе ошибочные (пока не сидел с дебаггером и не разбирался). Системы именования переменных и аргументов не придерживался, поэтому меняйте на свой вкус и цвет. Пробовал использовать Army для отряда на поле боя, но мне привычнее просто stack. Поменял несколько перечислителей (спеллы, флаги существ), если не понравятся названия, смело можете исправлять.

Названия AI_MeleeEnemy, AI_ShootingEnemy и AI_MostPowerfulEnemy, скорее всего, не соответствуют действительности. Поменял после того, как сравнил код взвешивания Shield и Air Shield, но всё, думаю, не так просто.
Вернуться к началу

Пред.След.

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

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

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