Объявления

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

Как создать плагин для HD мода

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

Re: Как создать плагин для HD мода

Сообщение igrik » 13 мар 2019, 16:43

Присоединение существ рассчитывается всего в 2х местах.
Если бы я хотел зафиксить дипломатию согласно ваших пунктов, то я бы ставил всего один HiHook на функцию 0x04A7230(hero, mon_ID). Думаю этого было бы достаточно. Но в полной мере сказать не могу на вскидку.
Это без учета правок HW_Rules
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение as239 » 13 мар 2019, 17:59

igrik писал(а):

Присоединение существ рассчитывается всего в 2х местах.
Если бы я хотел зафиксить дипломатию согласно ваших пунктов, то я бы ставил всего один HiHook на функцию 0x04A7230(hero, mon_ID). Думаю этого было бы достаточно. Но в полной мере сказать не могу на вскидку.
Это без учета правок HW_Rules


А вот с этим, п.3 я бы мог сделать.
Только не понятно:
1. Какой тип у mon_Id не похоже что int
2. Как оформлять возврат hihookа. Так вылетает:
return CALL_2(int, __thiscall, h->GetDefaultFunc(), Hero, mon_Id);
Вернуться к началу

offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

Re: Как создать плагин для HD мода

Сообщение igrik » 13 мар 2019, 19:12

Разобраная (навскидку) функция имеет такой вид
Код: Выделить всё
int __fastcall sub_004A7230(_Hero_* hero, int id)
{
  v2 = o_GameMgr->MapKind;
  Hero = hero;
  monID = id;
  value = 0;
  countAll = 0;
  if ( (v2 || id != 112 && id != 113 && id != 114 && id != 115) && *(_DWORD *)(o_pCreatureInfo + 116 * id) != -1 )
  {
    if ( !v2 && (id == 112 || id == 113 || id == 114 || id == 115) || (grade = GetMonsterUpgrade(id), grade == -1) )
    {
      if ( o_GameMgr->MapKind || monID != 123 && monID != 127 && monID != 125 && monID != 129 )
        grade = sub_0047AB50(monID);
      else
        grade = -1;
    }
  }
  else
  {
    grade = -1;
  }
  count = Hero + 173;
  i = 7;
  do
  {
    countTemp = *(_DWORD *)count;
    if ( *(_DWORD *)count > 0 )
    {
      countAll += countTemp;
      HeroStackType = *(_DWORD *)(count - 28);
      if ( HeroStackType == monID || HeroStackType == grade )
        value += 2 * countTemp;
    }
    count += 4;
    --i;
  }
  while ( i );
  result = value;
  if ( value )
    result = (value > countAll) + 1;
  return result;
}


HiHook на неё нужно ставить так
Код: Выделить всё
_int_ __stdcall Y_Diplo_GetDopValue_IfHero_HasThisMon(HiHook* hook, _Hero_* hero, _int_ mon_ID)
{

   sprintf(o_TextBuffer, "Номер героя: %d \n Номер монстра: %d", hero->id, mon_ID);
   b_MsgBox(o_TextBuffer, 1);


   _int_ ret = CALL_2(_int_, __fastcall, hook->GetDefaultFunc(), hero, mon_ID);

       if ( "если нам что то не нравится" ) {
           ret = 0;
       }

   return ret;
}

/////////////////////////////////////////////////////////////////////
_PI->WriteHiHook(0x4A7230, SPLICE_, EXTENDED_, FASTCALL_, Y_Diplo_GetDopValue_IfHero_HasThisMon);


PS: Хотя разобрав эту функцию я пришел к выводу, что с помощью неё полностью не решить запрос по всем пунктам.
Либо нужно передавать отрицательное значение, если результат не устраивает.
Короче нужно тестировать, а на это нужно время, которого у меня к сожелению совершенно не хватает
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение RoseKavalier » 14 мар 2019, 02:39

Yes this function calculates Sympathy.
The biggest issue with returning a negative value from this function if conditions are met is that in some cases where monsters would want to run, they will want to fight. Otherwise you can give -1000 and be done with it.
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение as239 » 14 мар 2019, 06:37

П.3 получилось сделать вот так:
Код: Выделить всё
int __stdcall Diplomacy( HiHook* hook, _Hero_* hero, _int_ mon_ID ) {
      
                _Army_ army = hero->army;
      bool IsStack = false;
      for (int i = 0; i < 7; ++i)
      {
         if  ( army.type[i] == mon_ID ) {
            IsStack = true;
            break;
         }
      }

      _int_ ret = CALL_2(_int_, __fastcall, hook->GetDefaultFunc(), hero, mon_ID);

      if (!IsStack) {
         ret = -4;
      }

      return ret;

}


Если возвращать 0 или -1000, то слабые нейтралы не убегают, а бьются.

Протестировал и понял что даже с этими 3-мя условиями, дипломатия ослабляется недостаточно.
Пример, вот на такую армию бесплатно присоединяются 69 уток:
Изображение
Буду думать дальше, что-то еще нужно добавлять.
Вернуться к началу

offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

Re: Как создать плагин для HD мода

Сообщение igrik » 14 мар 2019, 07:07

Тогда вот (опять же навскидку) разобраный участок кода, отвечающий за дипломатию при ПКМ на КП
начиная с 0x4171B4
Код: Выделить всё
        Simpathy = Diplo_GetSympathy((int)Hero, monID);
        diploPow = Hero->SSkill[4];
        LODWORD(simpathi) = Simpathy;
        diploPower = (_PlayerSetup_ *)diploPow;
        armyPower = Hero_GetArmyPower(Hero);
        LODWORD(armyPow) = armyPower;
        netrPow = monCount * *(_DWORD *)(116 * monID + o_pCreatureInfo + 64);
        heroArmPow = (long double)armyPower;
        armyPow = (long double)netrPow;
        heroArmPow = heroArmPow / armyPow;
        PowFactor = Diplo_GetPowFactor(heroArmPow);
        setupItem = a2->VTable;                 // тут mapItem->setup
        HeroChance = (int)((char *)diploPower + PowFactor + simpathi);
        a2 = (_Dlg_ *)setupItem;
        Loyaly = setupItem << 15 >> 27;
        if ( Loyaly > HeroChance )
          goto LABEL_33;
        if ( Loyaly <= (signed int)(&diploPower->HeroesCount + simpathi) )
        {
          typeDiplo = 2;  // бесплатное присоединение
          goto LABEL_15;
        }
        if ( Loyaly <= (_DWORD)simpathi + 2 * (_DWORD)diploPower + 1 )
        {
          typeDiplo = 3;  // присоединение за деньги
          goto LABEL_15;
        }
        if ( (unsigned int)a2 & 0x20000 || Loyaly == HeroChance )
LABEL_33:
          typeDiplo = 1;  // ринутся в драку
        else
          typeDiplo = 0;  // обратятся в бегство
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение as239 » 14 мар 2019, 08:32

А кто-нибудь знает как получить value отряда нейтралов?
Вернуться к началу

offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

Re: Как создать плагин для HD мода

Сообщение igrik » 14 мар 2019, 09:42

as239 писал(а):

А кто-нибудь знает как получить value отряда нейтралов?

Ну вот же прям в коде описано
Код: Выделить всё
netrPow = monCount * *(_DWORD *)(116 * monID + o_pCreatureInfo + 64);
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение as239 » 14 мар 2019, 12:46

igrik писал(а):

as239 писал(а):

А кто-нибудь знает как получить value отряда нейтралов?

Ну вот же прям в коде описано
Код: Выделить всё
netrPow = monCount * *(_DWORD *)(116 * monID + o_pCreatureInfo + 64);


Я не понимаю как сделать чтобы это значение выдавалось при ПКМ на монстре.
В существующем HiHookе нету monCount.
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение RoseKavalier » 14 мар 2019, 13:06

With HiHook it is more complicated to get all relevant information, monster count gets stored at [EBP - 10h] from 0x4170E8.

You could also try LoHook near 0x41722A (not ideal location) and directly affect ECX which is Charisma in AlexSpl's post.

ESI values after 0x417260 if needed:
Interaction Type
0 - Run
1 - Fight
2 - Join free
3 - Join $$$

There is almost a good candidate in HiHook (__thiscall) on 0x417295, problem here is Hero structure is not available, so you'd be stuck with a global variable.
[EDIT or simply get hero structure from _Player_ like the game does around 0x4170EB...]
Dlg_ForMonsterRMHint(_MonsterDlg_ *dlg, BOOL vision, int monsterID, int monsterCount, int interactionType, int joinCost);


Some time back I was asked how to nerf Diplomacy a bit, could give some ideas.
Цитата:
1- change army count for free joiners:
0x4A6C88
c->esi = max(1, (c->esi) >> 2); // integer division by 4, minimum value 1
return EXEC_DEFAULT;

2- change army count for joiners costing gold:
0x4A6EE8
c->edi = max(1, (c->edi) >> 2); // integer division by 4, minimum value 1
return EXEC_DEFAULT;

Also you could make neutrals think they are a larger group than in reality so they will not join as easily:
0x4A73DC
c->ebx += (c->ebx) >> 1; // artificially add 50% to creature count for power calculations
return EXEC_DEFAULT;
Вернуться к началу

Пред.След.

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

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

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

cron