Объявления

Форум о Героях Меча и Магии и King's Bounty. Если Вы любите эти игры, мы будем рады видеть Вас в наших рядах. :smile2:

Герои 2 (разные версии) с плагинами

Не запускается игра? Проблемы со звуком? Где, в конце концов, взять игру, скачать патчи, приложения и карты? Как установить все это? Все проблемы обсуждаем в этом разделе
offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1212
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 309 раз.

Re: Герои 2 (разные версии) с плагинами

Сообщение Ben80 » 01 дек 2021, 06:09

Maximus писал(а):

Плагин H2_70_AI_Imrovements

AI стало играть итересее, о на PoL 2.1 Eng - регулярные crash в произвольных моментах игры.


Здравствуйте. Точно отсюда скачали последнюю версию ? viewtopic.php?f=40&t=947&start=35
Я ведь обновлял этот файл несколько раз. Плохо, если ссылка идет для версии с крашем.

Можете еще попробовать отсюда взять - https://drive.google.com/file/d/1Bqg2UL ... sp=sharing

Пока что новых существенных улучшений ИИ не запланировано, хотя есть такая приятная мелочь, как освоение ИИ заклинания Teleport. Но скорее всего, это изменение ИИ попадет в модуль с изменения Gameplay, поскольку также придется менять вероятности попадания Teleport в ГМ.
Вернуться к началу

offlineАватара пользователя
Maximus  
имя: Maximus
Новичок
Новичок
 
Сообщения: 22
Зарегистрирован: 24 фев 2020, 10:56
Пол: Мужчина
Поблагодарили: 12 раз.

Re: Герои 2 (разные версии) с плагинами

Сообщение Maximus » 01 дек 2021, 06:27

Я посмотрел повнимательнее.
Ошибка воздникает в sуstem32\dsound.dll.

Возможно это связано wrapper, или патчером.
Вернуться к началу

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

Re: Герои 2 (разные версии) с плагинами

Сообщение Ben80 » 01 дек 2021, 06:39

Может быть и враппер или еще что-то. Я одно время играл на ноутбуке с глянцевым экраном (графика очень хорошая была благодаря GL Wrapper), там в первые полчаса игры краши бывали, потом устаканивалось. Возможно, с AUTOSAVE как-то связано...

Патчер бараторчевский, мне кажется, не дает вообще глюков. Если только по мелочам, о которых я не знаю.

Но если дело все-таки в моем модуле, то, конечно, подберем стабильную версию. Пишите в личку, если что - буду подыскивать стабильную версию. А так, сам играю - проблем не имею.
Вернуться к началу

offlineАватара пользователя
Maximus  
имя: Maximus
Новичок
Новичок
 
Сообщения: 22
Зарегистрирован: 24 фев 2020, 10:56
Пол: Мужчина
Поблагодарили: 12 раз.

Re: Герои 2 (разные версии) с плагинами

Сообщение Maximus » 01 дек 2021, 07:40

Выключил звук в игре - вылеты прекратились.
Так что к Вам вообще нет вопросов - отличная идея и отличая реализация. :smile11:
А еще можно было бы описать то, что добвлео в GameplayImprovements?
Вернуться к началу

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

Re: Герои 2 (разные версии) с плагинами

Сообщение Ben80 » 01 дек 2021, 07:59

Maximus писал(а):

А еще можно было бы описать то, что добвлео в GameplayImprovements?


Хорошо, опишу. Здесь есть список изменений https://heroes2.forumactif.com/t974-her ... es-and-mod
Хотя, думаю, стоит добавить "художественную часть", в которой написать, чего мне не хватило в оригинальной игре, и чего хочется в конечном итоге. Если коротко - красоты и путешествия по заповедным местам оригинальных карт прошли мимо меня, поскольку для победы обычно было достаточно обычной беготни от одного замка к другому. Соответственно, хотелось бы стимулировать альтернативный путь к победе через более полное освоение всей карты со всеми ее полезными объектами.
Изменения геймплея в этом направлении по сути еще не окончены.
Вернуться к началу

offlineАватара пользователя
Maximus  
имя: Maximus
Новичок
Новичок
 
Сообщения: 22
Зарегистрирован: 24 фев 2020, 10:56
Пол: Мужчина
Поблагодарили: 12 раз.

Re: Герои 2 (разные версии) с плагинами

Сообщение Maximus » 02 дек 2021, 08:07

Доброго времени суток.
Спасибо за описание. Прочитав форум, наверное думаю, все-таки не стоит переносить заклиания из уровня в уровень. :smile6: В остальном - отличное предложеие.
Я лично пользуюсь такими исправлениями:

KNIGHT CASTLE
Increased Peasant basic growth from 12 to 26 (total 26+2+8=36)
Decreased Peasant gold cost from 20 to 15
Increased Peasant speed from Very Slow to Slow
Increased Archer/Ranger hit points from 10 to 11
Increased Pikeman/Veteran Pikeman hit points from 15/20 to 16/21
Increased Pikeman/Veteran Pikeman damage from 3-4 to 3-5
Increased Pikeman/Veteran Pikeman gold cost from 200/250 to 210/260
Increased Swordsman/Master Swordsman hit points from 25/30 to 26/31
Increased Swordsman/Master Swordsman damage from 4-6 to 4-7
Increased Swordsman/Master Swordsman gold cost from 250/300 to 260/310
Increased Cavalry/Champion hit points from 30/40 to 35/45
Increased Cavalry/Champion gold cost from 300/375 to 340/415
Increased Paladin/Crusader hit points from 50/65 to 60/75
Increased Paladin gold cost from 600 to 675
Decreased Cathedral wood cost from 20 to 10
Decreased Upg. Cathedral cost from 10 wood, 10 crystal, 5000 gold to 10 wood, 5 crystal, 3500 gold
Decreased Fortifications wood/ore cost from 5/15 to 0/10


BARBARIAN CASTLE
Increased Goblin basic growth from 10 to 12 (total 12+2+8=22)
Increased Orc hit points from 10 to 11
Increased Wolf defense from 2 to 4
Increased Wolf gold cost from 200 to 210
Decreased Ogre Lord hit points from 60 to 55
Decreased Ogre Lord gold cost from 500 to 475
Decreased Troll/War Troll gold cost from 600/700 to 575/650
Increased Cyclops hit points from 80 to 85
Increased Cyclops gold cost from 750 to 800
Decreased Pyramid ore cost from 20 to 10
Decreased Coliseum cost from 10 wood, 10 ore, 2000 gold to 5 wood, 5 ore, 1500 gold


SORCERESS CASTLE
Increased Sprite basic growth from 8 to 10 (total 10+2+8=20)
Decreased Dwarf/Battle Dwarf gold cost from 200/250 to 190/235
Increased Elf Attack skill from 4 to 5
Increased Grand Elf Attack skill from 5 to 7
Increased Elf/Grand Elf hit points from 15 to 16
Increased Greater Druid hit points from 25 to 26
Increased Upg. Stonehenge gold cost from 1500 to 2000
Increased Unicorn hit points from 40 to 45
Increased Unicorn gold cost from 500 to 515
Changed Rainbow's mercury/crystal cost from 0/10 to 5/5


WARLOCK CASTLE
Increased Cave ore cost from 0 to 5
Decreased Crypt ore cost from 10 to 5
Decreased Gargoyle defense from 7 to 6
Increased Griffin gold cost from 300 to 320
Decreased Hydra gold cost from 800 to 775
Decreased Green/Red/Black Dragon basic growth from 1 to 0 (total 0+2=2)
Decreased Red/Black Dragon hit points from 250/300 to 240/280
Decreased Green Tower gold cost from 15000 to 13000
Increased Red/Black Tower gold cost from 5000 to 6000
Increased Dungeon cost from 5 wood, 10 ore, 3000 gold to 5 wood, 10 Ore, 3500 gold, and 3/3/3/3 rare


WIZARD CASTLE
Increased Halfling gold cost from 50 to 55
Increased Boar damage from 2-3 to 2-4
Increased Boar gold cost from 150 to 155
Increased Roc defense from 7 to 8
Decreased Upg. Ivory Tower gold cost from 4000 to 3000
Decreased Giant/Titan basic growth from 1 to 0 (total 0+2=2)
Increased Giant hit points from 150 to 155
Decreased Titan hit points from 300 to 280
Decreased Titan gold cost from 5000 to 4500
Decreased Cloud Castle gold cost from 12500 to 7500
Increased Upg. Cloud Castle gold cost from 12500 to 16500
Changed Titan "Fight Value" from 22933 to 27000


NECROMANCER CASTLE
Decreased Skeleton gold cost from 75 to 70
Increased Zombie speed from Very Slow to Slow
Increases Zombie/Mutant Zombie defense from 2 to 3
Decreased Zombie/Mutant Zombie gold cost from 150/200 to 140/190
Increased Mummy/Royal Mummy defense from 6 to 7
Changed Upg. Mansion cost from 5 wood, 10 crystal, 10 gems, 4000 gold to 5 wood, 10 mercury, 5 crystal, 3500 gold
Increased Lich hit points from 25 to 30 but decreased defense from 12 to 11.
Decreased Lich/Power Lich gold cost from 750/900 to 650/750
Changed Upg. Mausoleum cost from 5 ore, 5 crystal, 3000 gold to 5 ore, 5 sulfur, 2500 gold
Decreased Bone Dragon hit points from 150 to 140
Increased Bone Dragon gold cost from 1500 to 1600
Increased Laboratory mercury & gold cost from 5 mercury, 10000 gold to 10 mercury, 12000 gold


COMMON BUILDINGS
Decreased Mage Guild Lv2 rare resource cost from 4 to 2
Decreased Mage Guild Lv3 rare resource cost from 6 to 4
Decreased Mage Guild Lv4 rare resource cost from 8 to 6
Decreased Mage Guild Lv5 rare resource cost from 10 to 8
Decreased Shipyard wood cost from 20 to 15


HEROES
(Attack/Defense/Power/Knowledge)
Knight Lv 2-9: No change: 35/45/10/10
Knight Lv 10+: No change: 25/25/25/25
Barbarian Lv 2-9: No change: 55/35/5/5
Barbarian Lv 10+: No change: 25/25/25/25 (manual incorrect, it's NOT 30/30/20/20)
Sorceress Lv 2-9: 20/25/25/30 from 10/10/30/50
Sorceress Lv 10+: 20/25/25/30 from 20/20/30/30
Warlock Lv 2-9: 20/20/35/25 from 10/10/50/30
Warlock Lv 10+: No change: 20/20/30/30
Wizard Lv 2-9: 20/20/30/30 from 10/10/40/40
Wizard Lv 10+: No change: 20/20/30/30
Necro Lv 2-9: 25/25/25/25 from 15/15/35/35
Necro Lv 10+: No change: 25/25/25/25

SPELLS
Increased cost of Animate Dead from 10 to 15
Increased cost of Resurrection from 12 to 13
Decreased cost of Fireblast from 15 to 14
Increased cost of Holy Word from 12 to 14
Increased cost of Chain Lightning from 15 to 20
Increased cost of Meteor Shower from 15 to 18
Increased cost of Elemental Storm from 15 to 20
Increased cost of Resurrection True from 15 to 20
Increased cost of Armageddon from 20 to 30
Increased cost of Dimension Door from 10 to 20
Вернуться к началу

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

Re: Герои 2 (разные версии) с плагинами

Сообщение Ben80 » 02 дек 2021, 08:43

Maximus писал(а):

Доброго времени суток.
Спасибо за описание. Прочитав форум, наверное думаю, все-таки не стоит переносить заклиания из уровня в уровень. :smile6: В остальном - отличное предложеие.


Да, тут уж ничего не поделаешь - у каждого свой взгляд на "баланс" и на то что можно, а что нельзя :smile1: У меня всегда была такая дилемма при моддинге Героев 3. С одной стороны - желание улучшить игровой процесс (а в каких-то случаях не просто улучшить, а прямо скажем - починить, ибо сломан), с другой - желание играть в "старую, добрую игру", а не в какую-то новую.

Maximus писал(а):

Я лично пользуюсь такими исправлениями:


Оо, это отсюда
viewtopic.php?f=39&t=131
Баланс по UndeadHalfOrc.

Я когда первый раз увидел все эти 11 HP вместо 10 или 16 вместо 15 - был озадачен. Потом оказалось, что автор таким образом пытался балансировать еще и соотношение "меча и магии" (типа после удара заклинанием существо выживает, и у него остается 1 HP :smile12: ). Мне даже сами такие числа, если честно, совсем не нравятся, неэстетично это как-то... Но я не хотел вас расстроить, на вкус и цвет, как известно...

***

Maximus писал(а):

Спасибо за описание. Прочитав форум, наверное думаю, все-таки не стоит переносить заклиания из уровня в уровень. :smile6: В остальном - отличное предложеие.


Перенос - это конечно, плохо, но ошибки разработчиков в проектировании игрового процесса и игровом анализе, к сожалению, не оставляют другого выбора. Если, конечно, хочется повысить качество игры. Если перенос "Щита" приходится объяснять и оправдывать, то в случае с "Гипнозом" любому очевидно, что не место этому заклинанию на 5-м уровне. Основной альтернативой в случае с "Гипнозом" является, наверно, банальный запрет заклинания.
Вернуться к началу

offlineАватара пользователя
Maximus  
имя: Maximus
Новичок
Новичок
 
Сообщения: 22
Зарегистрирован: 24 фев 2020, 10:56
Пол: Мужчина
Поблагодарили: 12 раз.

Re: Герои 2 (разные версии) с плагинами

Сообщение Maximus » 02 дек 2021, 15:17

Да, действительно у меня мод от ПолуОрка :smile1: В те далекие времена, когда я его вшивал, особых вариантов не было - либо оригинальный движок, либо что-то более сбалансированное. Хотя Qwerty раскритиковал его ))) Но в любом случае играть стало все-таки интереснее. А уж после внесения H2_42, H2_47, H2_48, H2_49, H2_70 игра заиграла другими красками.
Думаю, используя UBP можно будет кое-что и подредактировать :smile6:
Я нисколько не обижен и не расстроен - альтернативная точка зрения всегда хорошо. Будем искать истину. :smile6:
А вот с переносом заклинаний - проблемы потом в редакторе сэйвов. Не видит он этих заклинаний на соотвтетствующем уровне :smile24: жаль не могу скрин прикрепить.
Вернуться к началу

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

Re: Герои 2 (разные версии) с плагинами

Сообщение Ben80 » 03 дек 2021, 06:12

Maximus писал(а):

Да, действительно у меня мод от ПолуОрка :smile1: В те далекие времена, когда я его вшивал, особых вариантов не было - либо оригинальный движок, либо что-то более сбалансированное. Хотя Qwerty раскритиковал его )))


Догадываюсь, что тогда больше ничего не было. С удовольствием читаю посты тех времен. Qwerty, как мне показалось, весьма положительно отнесся к патчу (в том числе по причине, указанной выше), но - да, отметил, что "с товарищами надо было посоветоваться".
Меня на самом деле заинтересовало снижение цен на ГМ по редким ресурсам. Я думал, что, возможно, далеко не все так играют, как я - стремятся строить жилища существ 6-го уровня, и совсем не горят желанием вкладываться в ГМ. Но, оказывается, не только я вижу здесь дисбаланс. Полагаю, снижу цену на 1 ед. редких ресурсов (на 2 - это уж слишком, как по мне).
А что, в самом деле это снижение цены на ГМ дает возможность альтернативного развития ?

Maximus писал(а):

Но в любом случае играть стало все-таки интереснее. А уж после внесения H2_42, H2_47, H2_48, H2_49, H2_70 игра заиграла другими красками.


В H2_47 нужды уже в общем нету, ибо включено в H2_48. H2_49 я бы вообще не советовал без нерфа некромантии. Хотя мне удалось пройти Terra Firma c H2_49 и без нерфа некромантии. Но в целом - не советую, дисбалансно, ИИ-некромант к тому же постоянно забивает своих ИИ-соседей.

Maximus писал(а):

Думаю, используя UBP можно будет кое-что и подредактировать :smile6:


Можно, только не получится то, что у меня изменено - например, снижение цен на личей и тд.

Maximus писал(а):

А вот с переносом заклинаний - проблемы потом в редакторе сэйвов. Не видит он этих заклинаний на соотвтетствующем уровне :smile24: жаль не могу скрин прикрепить.


Не знаю, почему так. У меня это изменение сделано органично - непосредственно в глобальной таблице свойств заклинаний. То есть по сути мои изменения в этом пункте эквивалентны HEX редактированию. Правда, я ничего не знаю о формате сейвов - могут ли быть какие-то особенности в том случае, если игра была начата без мода, а потом с модом, или наоборот. Ну и особенности вашей программы тоже не знаю - может быть, в ней где-то уже жестко прописано соответствие заклинаний и уровней ?
Вернуться к началу

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

Re: Герои 2 (разные версии) с плагинами

Сообщение Ben80 » 03 дек 2021, 11:16

Плагин, позволяющий ИИ использовать в бою заклинание Teleport.
Шанс выпадения заклинания в магических гильдиях увеличен по сравнению с оригинальной игрой.

Сам плагин:
H2_71_AI_TeleportSpell.zip
(5.21 КБ) Скачиваний: 116


Исходный код:
 
Код: Выделить всё
#include "../../include2021/patcher_x86.hpp"
#include "../../include2021/H2Structures.h"

#include <math.h>

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

int aSSpellInfo;
int aTag_monsterInfo;
int gpGame;

int bestTargetTeleportHex;
int targetTeleportHex;
int p_giNextActionGridIndex2;

int __stdcall AI_setGlobalTargetHex(LoHook* h, HookContext* c)
{
   if(h->GetAddress() == 0x486A07) // Eng 2.0
   {
      if(*(int*)(c->ebp - 0x8) == SPELL_TELEPORT)
         *(int*)p_giNextActionGridIndex2 = bestTargetTeleportHex;
   }
   else
   {
      if(*(int*)(c->ebp - 0x18) == SPELL_TELEPORT)
         *(int*)p_giNextActionGridIndex2 = bestTargetTeleportHex;
   }
   
   return EXEC_DEFAULT;
}

int __stdcall AI_setTargetHex(LoHook* h, HookContext* c)
{
   bestTargetTeleportHex = targetTeleportHex;
   
   return EXEC_DEFAULT;
}

int __stdcall AI_TeleportWeight(LoHook* h, HookContext* c)
{
   int currentWeight;
   int bestWeight = 0;
   army* AIStack;

   int hookAddress = h->GetAddress();

   if(hookAddress == 0x487895) // Eng 2.0
      AIStack = *(army**)(c->ebp - 0x28);
   else
      AIStack = *(army**)(c->ebp - 0x1C);

   combatManager* cm = *(combatManager**)(c->ebp - 0x44);
   combatManagerSW* cmSW = *(combatManagerSW**)(c->ebp - 0x44);

   int armyValidFlightProc;
   int spellCastWorkChanceProc;
   int armyOtherArmyAdjacentProc;

   // Eng 1.3
   if(hookAddress == 0x4B8900)
   {
      armyValidFlightProc = 0x46987C;
      spellCastWorkChanceProc = 0x409931;
      armyOtherArmyAdjacentProc = 0x40AA07;
   }
   // Eng 2.0
   if(hookAddress == 0x487895)
   {
      armyValidFlightProc = 0x4A5B95;
      spellCastWorkChanceProc = 0x452ECA;
      armyOtherArmyAdjacentProc = 0x453FA6;
   }
   // Eng 2.1
   if(hookAddress == 0x466B4C)
   {
      armyValidFlightProc = 0x4012C0;
      spellCastWorkChanceProc = 0x483590;
      armyOtherArmyAdjacentProc = 0x4846B0;
   }
   // Rus 2.1
   if(hookAddress == 0x496C4F)
   {
      armyValidFlightProc = 0x44B21E;
      spellCastWorkChanceProc = 0x420595;
      armyOtherArmyAdjacentProc = 0x4213BC;
   }
   // Pl 2.1
   if(hookAddress == 0x495F3B)
   {
      armyValidFlightProc = 0x44B750;
      spellCastWorkChanceProc = 0x420920;
      armyOtherArmyAdjacentProc = 0x4217A0;
   }
   // Cz 2.1 New
   if(hookAddress == 0x49512F)
   {
      armyValidFlightProc = 0x44AF8E;
      spellCastWorkChanceProc = 0x42041A;
      armyOtherArmyAdjacentProc = 0x421241;
   }
   // Cz 2.1 Old
   if(hookAddress == 0x49482F)
   {
      armyValidFlightProc = 0x44A67E;
      spellCastWorkChanceProc = 0x41FFC9;
      armyOtherArmyAdjacentProc = 0x420DF0;
   }

   int saveTargetOwner = AIStack->targetOwner;
   int saveTargetStackIdx = AIStack->targetStackIdx;
   int saveTargetNeighborIdx = AIStack->targetNeighborIdx;
   int saveTargetHex = AIStack->targetHex;

   int sourceRow = AIStack->occupiedHex / 13;
   int sourceCol = AIStack->occupiedHex % 13;

   int destRow;
   int destCol;
   int rowDistance;
   int colDistance;
   int deltaDistance;
   int distance;
   int distanceFactor;

   bool unchantedAIStack;
   bool unchantedTarget;

   if(hookAddress == 0x487895) // Eng 2.0
   {
      if(*(int*)(c->ebp - 0x8) == 0 && *(int*)(c->ebp - 0xC) == 0) // if not under enemy control, not incapacitated
         unchantedAIStack = false;
      else
         unchantedAIStack = true;
   }
   else
   {
      if(*(int*)(c->ebp - 0x20) == 0 && *(int*)(c->ebp - 0x30) == 0) // if not under enemy control, not incapacitated
         unchantedAIStack = false;
      else
         unchantedAIStack = true;
   }

   float spellChance = CALL_2(float, __thiscall, spellCastWorkChanceProc, AIStack, SPELL_TELEPORT);
   bool alreadyAdjacent = false;

   if(hookAddress != 0x4B8900) // if not Eng 1.3
   {
      if(spellChance > 0.01)
      if(unchantedAIStack == false) // if not under enemy control, not incapacitated
      if(!(AIStack->creature.creature_flags & FLYER) && !(AIStack->creature.creature_flags & SHOOTER))
      if(!(cm->currentActionSide && cm->isCastleBattle))
      for(int i=0; i < cm->numCreatures[1 - AIStack->owningSide]; i++)
      {
         unchantedTarget = cm->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_HYPNOTIZE] ||
         cm->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_BERSERKER] ||
         cm->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_BLIND] ||
         cm->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_PARALYZE] ||
         cm->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_PETRIFY];

         if(cm->creatures[1 - AIStack->owningSide][i].quantity > 0)
         if(cm->isCastleBattle || (cm->creatures[1 - AIStack->owningSide][i].creature.creature_flags & SHOOTER && unchantedTarget == false))
         {
            AIStack->targetOwner = cm->creatures[1 - AIStack->owningSide][i].owningSide;
            AIStack->targetStackIdx = cm->creatures[1 - AIStack->owningSide][i].stackIdx;
            AIStack->targetHex = cm->creatures[1 - AIStack->owningSide][i].occupiedHex;

            if(CALL_3(signed int, __thiscall, armyValidFlightProc, AIStack, AIStack->targetHex, 0))
            {
               destRow = cm->creatures[1 - AIStack->owningSide][i].occupiedHex / 13;
               destCol = cm->creatures[1 - AIStack->owningSide][i].occupiedHex % 13;

               colDistance = abs(destCol - sourceCol);
               rowDistance = abs(destRow - sourceRow);

               colDistance -= 2;
               if(colDistance < 0)
                  colDistance = 0;

               deltaDistance = (rowDistance + 1) / 2;
               if(deltaDistance > colDistance)
                  deltaDistance = colDistance;
               distance = colDistance + rowDistance - deltaDistance;

               distance -= 1;
               if(distance < 0)
                  distance = 0;

               distanceFactor = distance / AIStack->speed;

               currentWeight = sqrt((double)(AIStack->quantity * AIStack->creature.fight_value)) *
                  sqrt((double)(cm->creatures[1 - AIStack->owningSide][i].quantity * cm->creatures[1 - AIStack->owningSide][i].creature.fight_value));
               currentWeight = 0.2 * currentWeight * distanceFactor;

               if(cm->isCastleBattle)
               {
                  if(cm->creatures[1 - AIStack->owningSide][i].creature.creature_flags & SHOOTER)
                     currentWeight *= 3;
               }

               if(CALL_3(signed int, __thiscall, armyOtherArmyAdjacentProc, AIStack,
               cm->creatures[1 - AIStack->owningSide][i].owningSide,
               cm->creatures[1 - AIStack->owningSide][i].stackIdx))
                  alreadyAdjacent = true;

               if(currentWeight > bestWeight)
               {
                  bestWeight = currentWeight;
                  targetTeleportHex = AIStack->targetHex;
               }
            }

         }
      }
   }
   else
   {
      if(spellChance > 0.01)
      if(unchantedAIStack == false) // if not under enemy control, not incapacitated
      if(!(AIStack->creature.creature_flags & FLYER) && !(AIStack->creature.creature_flags & SHOOTER))
      if(!(cmSW->currentActionSide && cmSW->isCastleBattle))
      for(int i=0; i < cmSW->numCreatures[1 - AIStack->owningSide]; i++)
      {
         unchantedTarget = cmSW->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_HYPNOTIZE] ||
         cmSW->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_BERSERKER] ||
         cmSW->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_BLIND] ||
         cmSW->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_PARALYZE] ||
         cmSW->creatures[1 - AIStack->owningSide]->effectStrengths[EFFECT_PETRIFY];

         if(cmSW->creatures[1 - AIStack->owningSide][i].quantity > 0)
         if(cmSW->isCastleBattle || (cmSW->creatures[1 - AIStack->owningSide][i].creature.creature_flags & SHOOTER && unchantedTarget == false))
         {
            AIStack->targetOwner = cmSW->creatures[1 - AIStack->owningSide][i].owningSide;
            AIStack->targetStackIdx = cmSW->creatures[1 - AIStack->owningSide][i].stackIdx;
            AIStack->targetHex = cmSW->creatures[1 - AIStack->owningSide][i].occupiedHex;

            if(CALL_3(signed int, __thiscall, armyValidFlightProc, AIStack, AIStack->targetHex, 0))
            {
               destRow = cmSW->creatures[1 - AIStack->owningSide][i].occupiedHex / 13;
               destCol = cmSW->creatures[1 - AIStack->owningSide][i].occupiedHex % 13;

               colDistance = abs(destCol - sourceCol);
               rowDistance = abs(destRow - sourceRow);

               colDistance -= 2;
               if(colDistance < 0)
                  colDistance = 0;

               deltaDistance = (rowDistance + 1) / 2;
               if(deltaDistance > colDistance)
                  deltaDistance = colDistance;
               distance = colDistance + rowDistance - deltaDistance;

               distance -= 1;
               if(distance < 0)
                  distance = 0;

               distanceFactor = distance / AIStack->speed;

               currentWeight = sqrt((double)(AIStack->quantity * AIStack->creature.fight_value)) *
                  sqrt((double)(cmSW->creatures[1 - AIStack->owningSide][i].quantity * cmSW->creatures[1 - AIStack->owningSide][i].creature.fight_value));
               currentWeight = 0.2 * currentWeight * distanceFactor;

               if(cmSW->isCastleBattle)
               {
                  if(cmSW->creatures[1 - AIStack->owningSide][i].creature.creature_flags & SHOOTER)
                     currentWeight *= 3;
               }

               if(CALL_3(signed int, __thiscall, armyOtherArmyAdjacentProc, AIStack,
               cmSW->creatures[1 - AIStack->owningSide][i].owningSide,
               cmSW->creatures[1 - AIStack->owningSide][i].stackIdx))
                  alreadyAdjacent = true;

               if(currentWeight > bestWeight)
               {
                  bestWeight = currentWeight;
                  targetTeleportHex = AIStack->targetHex;
               }
            }

         }
      }
   }

   AIStack->targetOwner = saveTargetOwner;
   AIStack->targetStackIdx = saveTargetStackIdx;
   AIStack->targetNeighborIdx = saveTargetNeighborIdx;
   AIStack->targetHex = saveTargetHex;

   if(hookAddress == 0x487895) // Eng 2.0
   {
      if(alreadyAdjacent)
         *(int*)(c->ebp - 0x2C) = 0;
      else
         *(int*)(c->ebp - 0x2C) = (int)(bestWeight * spellChance);
   }
   else
   {
      if(alreadyAdjacent)
         *(int*)(c->ebp - 0x34) = 0;
      else
         *(int*)(c->ebp - 0x34) = (int)(bestWeight * spellChance);
   }

    return NO_EXEC_DEFAULT;
}

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("H2_AI_TeleportSpell");

            int check;


            // H2 Eng SW 1.3
            check = *(int*)(0x434317+6);
            if(check == 0x14000000)
            {
            gpGame = 0x520DA4;
            aTag_monsterInfo = 0x4F12B8;
            aSSpellInfo = 0x4F2280;
            p_giNextActionGridIndex2 = 0x51F6FC;

            _PI->WriteLoHook(0x4B8900, AI_TeleportWeight);
            _PI->WriteLoHook(0x4B8B2C, AI_setTargetHex);
            _PI->WriteLoHook(0x4B7A74, AI_setGlobalTargetHex);

            ((SSpellInfo*)aSSpellInfo)[SPELL_TELEPORT].appearingChance = 400;
            }

            // H2 Eng PoL 2.0
            check = *(int*)(0x41BFB7+6);
            if(check == 0x14000000)
            {
            gpGame = 0x5290A8;
            aTag_monsterInfo = 0x4FAEB0;
            aSSpellInfo = 0x4FBE78;
            p_giNextActionGridIndex2 = 0x52510C;

            _PI->WriteLoHook(0x487895, AI_TeleportWeight);
            _PI->WriteLoHook(0x487AC1, AI_setTargetHex);
            _PI->WriteLoHook(0x486A07, AI_setGlobalTargetHex);

            ((SSpellInfo*)aSSpellInfo)[SPELL_TELEPORT].appearingChance = 400;
            }

            // H2 Eng PoL 2.1
            check = *(int*)(0x484DC1+6);
            if(check == 0x14000000)
            {
            aSSpellInfo = 0x4F31C0;
            aTag_monsterInfo = 0x4F21F8;
            gpGame = 0x52477C;
            p_giNextActionGridIndex2 = 0x524C68;

            _PI->WriteLoHook(0x466B4C, AI_TeleportWeight);
            _PI->WriteLoHook(0x466D78, AI_setTargetHex);
            _PI->WriteLoHook(0x465CB7, AI_setGlobalTargetHex);

            ((SSpellInfo*)aSSpellInfo)[SPELL_TELEPORT].appearingChance = 400;

            }

            // H2 Rus PoL 2.1
            check = *(int*)(0x4710BE+6);
            if(check == 0x14000000)
            {
            gpGame = 0x526124;
            aTag_monsterInfo = 0x4FA460;
            aSSpellInfo = 0x4FB3B8;
            p_giNextActionGridIndex2 = 0x52510C;

            _PI->WriteLoHook(0x496C4F, AI_TeleportWeight);
            _PI->WriteLoHook(0x496D52, AI_setTargetHex);
            _PI->WriteLoHook(0x495F88, AI_setGlobalTargetHex);

            ((SSpellInfo*)aSSpellInfo)[SPELL_TELEPORT].appearingChance = 400;
            }

            // H2 Pol PoL 2.1
            check = *(int*)(0x470C7C+6);
            if(check == 0x14000000)
            {
            gpGame = 0x51DD88;
            aTag_monsterInfo = 0x4EF2A8;
            aSSpellInfo = 0x4F0200;
            p_giNextActionGridIndex2 = 0x51BEF0;

            _PI->WriteLoHook(0x495F3B, AI_TeleportWeight);
            _PI->WriteLoHook(0x49603E, AI_setTargetHex);
            _PI->WriteLoHook(0x495268, AI_setGlobalTargetHex);

            ((SSpellInfo*)aSSpellInfo)[SPELL_TELEPORT].appearingChance = 400;
            }

            // H2 Cz PoL 2.1 New
            check = *(int*)(0x47091E+6);
            if(check == 0x14000000)
            {
            gpGame = 0x52187C;
            aTag_monsterInfo = 0x4F4690;
            aSSpellInfo = 0x4F5610;
            p_giNextActionGridIndex2 = 0x51F9A0;

            _PI->WriteLoHook(0x49512F, AI_TeleportWeight);
            _PI->WriteLoHook(0x495232, AI_setTargetHex);
            _PI->WriteLoHook(0x494468, AI_setGlobalTargetHex);

            ((SSpellInfo*)aSSpellInfo)[SPELL_TELEPORT].appearingChance = 400;
            }

            // H2 Cz PoL 2.1 Old
            check = *(int*)(0x47000E+6);
            if(check == 0x14000000)
            {
            gpGame = 0x51C9DC;
            aTag_monsterInfo = 0x4F1538;
            aSSpellInfo = 0x4F24B8;
            p_giNextActionGridIndex2 = 0x51AB00;

            _PI->WriteLoHook(0x49482F, AI_TeleportWeight);
            _PI->WriteLoHook(0x494932, AI_setTargetHex);
            _PI->WriteLoHook(0x493B68, AI_setGlobalTargetHex);

            ((SSpellInfo*)aSSpellInfo)[SPELL_TELEPORT].appearingChance = 400;
            }

        }
    }

   return TRUE;
}

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

Пред.След.

Вернуться в Техническая часть

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

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

cron