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


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

Улучшение ИИ

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

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

Сообщение RoseKavalier » 08 май 2020, 20:12

Not yet... now yes.
Вернуться к началу

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 » 09 май 2020, 01:35

Плагин для проверки работы функции sub_423C80 (AI_CalcBattleStack_GetCastSpellValue):

Код: Выделить всё
#define _H3API_PATCHER_X86_
#include "..\..\H3API\H3API.hpp"

Patcher* _P;
PatcherInstance* _PI;
const char* PLUGIN_NAME = "HD.Plugin.TestH3API";
static _bool_ plugin_On = 0;

using namespace h3;

int __stdcall AIGetCastSpellValue(HiHook* hook, H3QuickBattleCreatures* battleStack, H3AIBattleSpell* spell, H3Hero* DHero, H3Hero* AHero)
{
   static int testNumber = 0;
      
   // Original function
   int OriginalValue = THISCALL_4(int, hook->GetDefaultFunc(), battleStack, spell, DHero, AHero);
      
   // Function to check
   int ValueToCheck = 0;
   double spellDamagePercentage;
   if ( battleStack->stackPower )
   {
      int spellDuration = spell->spellDuration;
      if ( spellDuration > 5 ) spellDuration = 5;
      spellDamagePercentage = FASTCALL_4(double, 0x44A1A0, spell->spellId, battleStack->type, DHero, AHero);
      ValueToCheck = (int)(battleStack->stackPower * spellDuration * P_Spell(spell->spellId).ai_value[spell->skillLevel] * spellDamagePercentage / 500.0);
   }

   // if ( ValueToCheck != OriginalValue )
   if ( ++testNumber <= 50 )
   {
      sprintf(h3_TextBuffer, "Test #%d\n\nOriginalValue = %d\nValueToCheck = %d\n\nstackPower = %d\nspellDuration = %d\nspellAIValue = %d\nspellDamage%% = %f",
         testNumber, OriginalValue, ValueToCheck, battleStack->stackPower, spell->spellDuration, P_Spell(spell->spellId).ai_value[spell->skillLevel], spellDamagePercentage);

      F_MessageBox();
   }
   
   return OriginalValue;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
      if ( !plugin_On )
      {
         plugin_On = 1;
         _P = GetPatcher();
         _PI = _P->CreateInstance(PLUGIN_NAME);
         _PI->WriteHiHook(0x423C80, SPLICE_, EXTENDED_, THISCALL_, AIGetCastSpellValue);
      }
    }

    return TRUE;
}

Декомпилировал я почти верно :smile1: Только в CalcSpellDamagePercentage() первым параметром нужно передавать номер заклинания (spellId), а не адрес соответствующей структуры H3Spell. Пропустите ход и наблюдайте за мыслью компа :smile1:
Вернуться к началу

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

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

Сообщение as239 » 09 май 2020, 09:14

Я правильно перевел флаги:
Код: Выделить всё
   
P_Spell[H3Spell::SACRIFICE].flags.AI_creatures = 1;// |= 0x80000
P_Spell[H3Spell::FORGETFULNESS].flags.AI_non_damage_spells = 1;//|= 0x40000;
P_Spell[H3Spell::TITANS_LIGHTNING_BOLT].flags.AI_adventure_map = 0; //&= 0xFFEFFFFF;


И какие значения лучше установить чтобы ИИ использовал эти заклинания:
Disguise, Quicksand, Land Mine, Force Field.
В первую очередь интересуют Мины и Зыбучие пески, против человека их использование выглядит интересно.
Вернуться к началу

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

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

Сообщение Ben80 » 09 май 2020, 10:14

Да, все правильно.

Реализация эффективного использования заклинания Disguise ИИ возможна и была бы интересна, но требует слишком большого количества усилий. По Force Field в принципе могу сказать то же самое, кроме того, что это не так интересно )
По Land Mine и Quicksand - реализация была бы не очень сложной. Но ИИ в любом случае не сможет их использовать достаточно эффективно. Да и человек использует их эффективно только через знание алгоритмов движения юнитов ИИ на поле боя. Если прописать ИИ юнитам более непредсказуемую траекторию движения, то даже человек их не сможет эффективно использовать.

Наиболее перспективной была бы реализация Берсерка для ИИ. Но реализация требует использования MovementManager на поле боя. С MovementManager я еще не разбирался. Зато для некоторых задач смог прикрутить свой собственный 'MovementManager" на карте приключений через реализацию алгоритма Дейкстры.
Вернуться к началу

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

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

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

Мины и пески я хотел бы включить для случая, когда у ИИ есть такой свиток, и нет ни какой другой эффективной магии.
Цитата:
Зато для некоторых задач смог прикрутить свой собственный 'MovementManager" на карте приключений через реализацию алгоритма Дейкстры.

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

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

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

Сообщение Ben80 » 09 май 2020, 12:14

Может использоваться для самых разных целей (так же, как и оригинальный MovementManager). Определить расстояние от героя до объекта (и саму возможность достигнуть объекта). Также может быть применено к задачам "постанализа" генерации случайных карт - определить возможность прохода из одной зоны в другую, возможность обхода монстра, охраняющего проход.
Вернуться к началу

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

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

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

Хотел отметить интересную особенность расчета ИИ веса для втор. навыков Школ магии. Если у героя совсем нет данной Школы, то берется разница с экспертным уровнем, а не базовым (sub_00525200).

Я у себя хотел реализовать примерно также, только итоговый вес еще и делить на 3 :)

Код: Выделить всё
int __stdcall magicSchoolsAIWeightFix(LoHook* h, HookContext* c)
{
   if(*(_byte_*)(c->ebp - 0x14) < 1)
      c->ebx /= 3;

    return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x52527E, magicSchoolsAIWeightFix);
Вернуться к началу

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

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

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

Есть желание полностью переписать хайхуком функцию sub_00527C40, где для лучшего заклинания расчитывается разница между эффективностью для текущего состояния героя и состояний, где он имеет разные прибавки - в колд.силе, мане и тд.
Идея в том, чтобы брать не единственное самое лучшее заклинание, а среднее по лучшим заклинаниям в своей группе. Скажем, можно разделить все заклинания на 3 группы: 1) дамажные 2) недамажные 3) карты приключений.
То есть там, где в оригинале функция sub_00527A90 вызывается из sub_00527C40 1 раз - у меня будет вызываться 3 раза.
Это, конечно, если я не поленюсь все это сделать :smile1:

Просто отмечаю недостаток текущей реализации с единственным лучшим спеллом - такие навыки, как Волшебство, Грамотность, Орлиный глаз, Мистицизм, Интеллект, Мудрость часто имеют то крайне низкие значения, то весьма высокие.
Вернуться к началу

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

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

Сообщение Ben80 » 10 май 2020, 09:15

Кстати, при желании можно сделать достаточно много AI групп для заклинаний, даже больше, чем в оригинале, используя для этого неиспользуемые флаги в SpellFlags.
Скажем, для Медлительности и Ускорения можно создать свою группу, или даже каждому из этих спеллов - по группе.
При этом расчет эффективности для каждого заклинания будет производиться по старым алгоритмам, просто вместо одного лучшего заклинания будет усредненное значение для ряда групп заклинаний.
Вернуться к началу

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

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

Сообщение as239 » 10 май 2020, 09:30

А какая функция рассчитывает доступную ману героя?
Можно, конечно, самому посчитать, но через родную функцию было бы лучше.

Обновлено:
Готовой функции нет, при выводе вот так считается:
Код: Выделить всё
v34 = unk_00698B70->SSkill[24];
          Mesd = IntelligenceSkillMultipliers[v34];
          if ( v34 > 0 )
          {
            v35 = &(*HeroSpecStrPo)[unk_00698B70->Number];
            if ( !v35->Spec && v35->Spec1 == 24 )
            {
              *(float *)&ArtDescr.SpellNum = (long double)unk_00698B70->ExpLevel;
              Mesd = (*(float *)&ArtDescr.SpellNum * 0.050000001 + 1.0) * Mesd;
            }
          }
          *(float *)&ArtDescr.SpellNum = (long double)(10 * v33);
          sprintf(
            (int)o_TextBuffer,
            *(const char **)(o_GENRLTXT->GetString + 824),
            unk_00698B70->Name,
            unk_00698B70->SpPoints,
            (unsigned int)(signed __int64)((Mesd + 1.0) * *(float *)&ArtDescr.SpellNum));
Последний раз редактировалось as239 10 май 2020, 09:44, всего редактировалось 1 раз.
Вернуться к началу

Пред.След.

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

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

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

cron