Объявления

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

Улучшение ИИ

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
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: Улучшение ИИ

Сообщение AlexSpl » 05 май 2020, 17:34

Добавьте рандом в функцию :smile2:

Т.е. если это город такого-то класса и уровень существ такой-то, то если Random(1, 100) > 75, то умножаем коэффициент на 100, например, если нет - возвращаем дефолт.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Улучшение ИИ

Сообщение as239 » 05 май 2020, 17:37

Кстати вариант :)
Только надо ее еще как-то по дням распределить.
Наверное просто сделаю один раз за первую неделю.
Вернуться к началу

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: Улучшение ИИ

Сообщение AlexSpl » 05 май 2020, 17:43

Можно просто проверять, если ли уже грейд.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Улучшение ИИ

Сообщение as239 » 05 май 2020, 17:45

Но она же будет срабатывать каждый день.
И в итоге за неделю грейд скорее всего всегда будет.
Вернуться к началу

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: Улучшение ИИ

Сообщение AlexSpl » 05 май 2020, 17:51

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

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Улучшение ИИ

Сообщение as239 » 05 май 2020, 17:52

Ну да, это я уже все осилю, спасибо большое!
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Улучшение ИИ

Сообщение as239 » 07 май 2020, 05:32

Не понимаю какой синтаксис для получения массива v41[44] [esp+58Ch] [ebp-114h] в LowHook по 0x42B1E2

...
Вот так вроде получилось:

Код: Выделить всё
int BuildingsWeightsFirst = (int)(c->ebp - 0x114);
int *Adress;
Adress = (int*)(BuildingsWeightsFirst + 4 * Built);
*Adress = 1000000;
Вернуться к началу

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: Улучшение ИИ

Сообщение AlexSpl » 07 май 2020, 09:25

Код: Выделить всё
int* BuildingsWeightsFirst = (int*)(c->ebp - 0x114);
BuildingsWeightsFirst[Built] = 1000000;
Вернуться к началу

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: Улучшение ИИ

Сообщение AlexSpl » 07 май 2020, 10:46

Вот скажите, пожалуйста, почему функция sub_5C14F0 (GetResourcesRequirements) декомпилируется как

Код: Выделить всё
int __thiscall GetResourcesRequirements(int this, signed int a2, void *a3)
{
  int result; // eax

  result = a2;
  if ( a2 >= 17 )
  {
    result = *(char *)(this + 4) + a2 + 8 * *(char *)(this + 4) - 17;
    qmemcpy(a3, &TownSpecBuildingResourcesReq[28 * result], 28u);
  }
  else
  {
    qmemcpy(a3, &TownNormalBuildingResourcesReq[7 * a2], 28u);
  }
  return result;
}

?

Куда подевался случай, когда a2 >= 30 с веткой TownDwellingResourcesReq? Я считаю это критической ошибкой декомпиляции.

Ассемблерный листинг:

Код: Выделить всё
.text:005C14F0 ; int __thiscall GetResourcesRequirements(int this, int a2, int a3)
.text:005C14F0 GetResourcesRequirements proc near                          ; CODE XREF: sub_0042AE00+60C↑p
.text:005C14F0                                                             ; sub_0042BEB0+13A↑p ...
.text:005C14F0
.text:005C14F0 a2                  = dword ptr  8
.text:005C14F0 a3                  = dword ptr  0Ch
.text:005C14F0
.text:005C14F0                     push    ebp
.text:005C14F1                     mov     ebp, esp
.text:005C14F3                     mov     eax, [ebp+a2]
.text:005C14F6                     push    esi
.text:005C14F7                     cmp     eax, 17                         ; Compare Two Operands
.text:005C14FA                     push    edi
.text:005C14FB                     jge     short loc_005C151D              ; Jump if Greater or Equal (SF=OF)
.text:005C14FD                     mov     edi, [ebp+a3]
.text:005C1500                     lea     ecx, ds:0[eax*8]                ; Load Effective Address
.text:005C1507                     sub     ecx, eax                        ; Integer Subtraction
.text:005C1509                     lea     esi, TownNormalBuildingResourcesReq[ecx*4] ; Load Effective Address
.text:005C1510                     mov     ecx, 7
.text:005C1515                     rep movsd                               ; Move Byte(s) from String to String
.text:005C1517                     pop     edi
.text:005C1518                     pop     esi
.text:005C1519                     pop     ebp
.text:005C151A                     retn    8                               ; Return Near from Procedure
.text:005C151D ; ---------------------------------------------------------------------------
.text:005C151D
.text:005C151D loc_005C151D:                                               ; CODE XREF: GetResourcesRequirements+B↑j
.text:005C151D                     movsx   ecx, byte ptr [ecx+4]           ; Move with Sign-Extend
.text:005C1521                     cmp     eax, 30                         ; Compare Two Operands
.text:005C1524                     jge     short loc_005C154D              ; Jump if Greater or Equal (SF=OF)
.text:005C1526                     lea     edx, [eax+ecx*8]                ; Load Effective Address
.text:005C1529                     mov     edi, [ebp+a3]
.text:005C152C                     lea     eax, [ecx+edx-17]               ; Load Effective Address
.text:005C1530                     lea     ecx, ds:0[eax*8]                ; Load Effective Address
.text:005C1537                     sub     ecx, eax                        ; Integer Subtraction
.text:005C1539                     lea     esi, TownSpecBuildingResourcesReq[ecx*4] ; Load Effective Address
.text:005C1540                     mov     ecx, 7
.text:005C1545                     rep movsd                               ; Move Byte(s) from String to String
.text:005C1547                     pop     edi
.text:005C1548                     pop     esi
.text:005C1549                     pop     ebp
.text:005C154A                     retn    8                               ; Return Near from Procedure
.text:005C154D ; ---------------------------------------------------------------------------
.text:005C154D
.text:005C154D loc_005C154D:                                               ; CODE XREF: GetResourcesRequirements+34↑j
.text:005C154D                     lea     edx, ds:0[ecx*8]                ; Load Effective Address
.text:005C1554                     mov     edi, [ebp+a3]
.text:005C1557                     sub     edx, ecx                        ; Integer Subtraction
.text:005C1559                     lea     eax, [eax+edx*2-30]             ; Load Effective Address
.text:005C155D                     lea     ecx, ds:0[eax*8]                ; Load Effective Address
.text:005C1564                     sub     ecx, eax                        ; Integer Subtraction
.text:005C1566                     lea     esi, TownDwellingResourcesReq[ecx*4] ; Load Effective Address
.text:005C156D                     mov     ecx, 7
.text:005C1572                     rep movsd                               ; Move Byte(s) from String to String
.text:005C1574                     pop     edi
.text:005C1575                     pop     esi
.text:005C1576                     pop     ebp
.text:005C1577                     retn    8                               ; Return Near from Procedure
.text:005C1577 GetResourcesRequirements endp

Ghidra не ошибается (хоть и не распознаёт qmemcpy()):

Код: Выделить всё
void __thiscall FUN_005c14f0(int param_1,int param_1_00,undefined4 *param_2)

{
  int iVar1;
  undefined4 *puVar2;
 
  if (param_1_00 < 0x11) {
    iVar1 = 7;
    puVar2 = &DAT_006a8160 + param_1_00 * 7;
    while (iVar1 != 0) {
      iVar1 = iVar1 + -1;
      *param_2 = *puVar2;
      puVar2 = puVar2 + 1;
      param_2 = param_2 + 1;
    }
    return;
  }
  if (param_1_00 < 0x1e) {
    iVar1 = 7;
    puVar2 = &DAT_006a8344 + ((int)*(char *)(param_1 + 4) * 9 + -0x11 + param_1_00) * 7;
    while (iVar1 != 0) {
      iVar1 = iVar1 + -1;
      *param_2 = *puVar2;
      puVar2 = puVar2 + 1;
      param_2 = param_2 + 1;
    }
    return;
  }
  iVar1 = 7;
  puVar2 = &DAT_006a9880 + (int)(&DAT_ffffffe2 + (int)*(char *)(param_1 + 4) * 0xe + param_1_00) * 7
  ;
  while (iVar1 != 0) {
    iVar1 = iVar1 + -1;
    *param_2 = *puVar2;
    puVar2 = puVar2 + 1;
    param_2 = param_2 + 1;
  }
  return;
}
Вернуться к началу

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: Улучшение ИИ

Сообщение AlexSpl » 07 май 2020, 12:00

Давайте декомпилируем руками.

Код: Выделить всё
mov eax, [ebp+a2]; c->eax = a2;


0. Ветка a2 < 17:
Код: Выделить всё
mov edi, [ebp+a3]; Задаём приёмник ((void*)a3) для rep movsd / qmemcpy();
lea ecx, ds:0[eax*8]; c->ecx = 8 * a2;
sub ecx, eax; c->ecx = 8 * a2 - a2 = 7 * a2;
lea esi, TownNormalBuildingResourcesReq[ecx*4]; Задаём источник для rep movsd / qmemcpy();
mov ecx, 7; Кол-во копируемых двойных слов
rep movsd; Собственно копирование 7 * 4 = 28 байтов


Итак,
Код: Выделить всё
if (a2 < 17) {
   qmemcpy((void*)a3, &TownNormalBuildingResourcesReq[28 * a2], 28); // *
   return;
}

* В базе Heroes3f TownNormalBuildingResourcesReq определёна как dd, а не db, поэтому в листинге IDA индекс [7 * a2].

Код: Выделить всё
movsx ecx, byte ptr [ecx+4]; c->ecx = *(char*)(this + 4); (общая команда для веток 1 и 2)


1. Ветка a2 < 30:
Код: Выделить всё
lea edx, [eax+ecx*8]; c->edx = a2 + 8 * *(char*)(this + 4);
mov edi, [ebp+a3]; Задаём приёмник ((void*)a3) для rep movsd / qmemcpy();
lea eax, [ecx+edx-17]; c->eax = *(char*)(this + 4) + a2 + 8 * *(char*)(this + 4) - 17 = a2 + 9 * *(char*)(this + 4) - 17;
lea ecx, ds:0[eax*8]; c->ecx = 8 * (a2 + 9 * *(char*)(this + 4) - 17);
sub ecx, eax; c->ecx = 7 * (a2 + 9 * *(char*)(this + 4) - 17);
lea esi, TownSpecBuildingResourcesReq[ecx*4]; Задаём источник для rep movsd / qmemcpy();
mov ecx, 7; Кол-во копируемых двойных слов
rep movsd; Собственно копирование 7 * 4 = 28 байтов


Итак,
Код: Выделить всё
if (a2 < 30) {
   qmemcpy((void*)a3, &TownSpecBuildingResourcesReq[28 * (a2 + 9 * *(char*)(this + 4) - 17)], 28);
   return;
}


2. Ветка a2 >= 30:
Код: Выделить всё
lea edx, ds:0[ecx*8]; c->edx = 8 * *(char*)(this + 4);
mov edi, [ebp+a3]; Задаём приёмник ((void*)a3) для rep movsd / qmemcpy();
sub edx, ecx; c->edx = 7 * *(char*)(this + 4);
lea eax, [eax+edx*2-30]; c->eax = a2 + 14 * *(char*)(this + 4) - 30;
lea ecx, ds:0[eax*8]; c->ecx = 8 * (a2 + 14 * *(char*)(this + 4) - 30);
sub ecx, eax; c->ecx = 7 * (a2 + 14 * *(char*)(this + 4) - 30);
lea esi, TownDwellingResourcesReq[ecx*4]; Задаём источник для rep movsd / qmemcpy();
mov ecx, 7;
rep movsd; Собственно копирование 7 * 4 = 28 байтов


Итак,
Код: Выделить всё
qmemcpy((void*)a3, &TownDwellingResourcesReq[28 * (a2 + 14 * *(char*)(this + 4) - 30)], 28);
return;


Итого:
Код: Выделить всё
int __thiscall GetResourcesRequirements(int this, int a2, int a3)
{
   if (a2 < 17) {
      qmemcpy((void*)a3, &TownNormalBuildingResourcesReq[28 * a2], 28);
      return;
   }
   
   if (a2 < 30) {
      qmemcpy((void*)a3, &TownSpecBuildingResourcesReq[28 * (a2 + 9 * *(char*)(this + 4) - 17)], 28);
      return;
   }
   
   qmemcpy((void*)a3, &TownDwellingResourcesReq[28 * (a2 + 14 * *(char*)(this + 4) - 30)], 28);
   return;
}


28 - очевидно sizeof(_Resource_). Тогда аргумент a3 имеет тип _Resource_.

 
Код: Выделить всё
int __thiscall GetResourcesRequirements(int this, int n, _Resource_& Res)
{
   if (n < 17) {
      Res = TownNormalBuildingResourcesReq[n];
      return;
   }
   
   if (n < 30) {
      Res = TownSpecBuildingResourcesReq[n + 9 * *(char*)(this + 4) - 17];
      return;
   }
   
   Res = TownDwellingResourcesReq[n + 14 * *(char*)(this + 4) - 30];
   return;
}
Последний раз редактировалось AlexSpl 07 май 2020, 13:34, всего редактировалось 5 раз(а).
Вернуться к началу

Пред.След.

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

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

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