Объявления

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

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

Герои Меча и Магии 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: Как создать плагин для HD мода

Сообщение AlexSpl » 23 авг 2021, 21:08

Цитата:
В общем нашел баг с закраской кол-ва цветом при снятии и наложении заклов. Бывает, что закл еще наложен, картинка в инфо окне существа отображается и кол-во оставшихся раундов также, а цвет уже стандартный как будто на отряде нет никаких заклов. Или наоборот на отряде уже нет никаких заклов, а цвет красный или зеленый как будто на нем высят какие-то заклы.

Тоже заметил. Не все участки, работающие с длительностью заклинаний, найдены. А Притяжение и Регенерация в MoP теряют в длительности?

Полезные исходники. Есть адреса, которые я пока не нашёл :smile20:
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 23 авг 2021, 21:48

AlexSpl писал(а):

А Притяжение и Регенерация в MoP теряют в длительности?

Да, теряют, там все четко.

Кстати, Лечение и Диспел пока что не снимают наши наложенные заклы. Я так понял до этого вы еще не добрались, верно?
Вернуться к началу

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: Как создать плагин для HD мода

Сообщение AlexSpl » 23 авг 2021, 21:51

Думаю, как добавлю адреса из MoP, многое заработает :smile2: Я только переживаю за active_spells_power[]. Так не хочется переносить... Представляю, как больно было переписывать функцию updateSpellsFromArtifacts(). Попробуй потом разберись в коде на asm, а на C++ через битсеты - всё красиво и понятно.

 С дополнениями из MoP...
...теми, что пока разобрал:

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include <bitset>
#include "..\..\HotA\homm3.h"

#define SPELLS_MAX 128
#define ANIMS_MAX 128
#define ADVSPELLS_NUM 10
#define SPECABIL_NUM 11
#define ARTIFACTS_NUM 144

#define SPELLS_NUM 87
#define SPL_FEAR_NEW 81
#define SPL_POISON_NEW 82
#define SPL_DISEASE_NEW 83
#define SPL_AGING_NEW 84
#define SPL_DEATH_CLOUD_NEW 85
#define SPL_DEATH_BLOW_NEW 86

#define ANIMS_NUM 89
#define ANIM_FEAR_NEW 83
#define ANIM_POISON_NEW 84
#define ANIM_DISEASE_NEW 85
#define ANIM_AGING_NEW 86
#define ANIM_DEATH_CLOUD_NEW 87
#define ANIM_DEATH_BLOW_NEW 88

Patcher* _P;
PatcherInstance* _PI;

struct _ComboArtInfo_ {
   int index;
   std::bitset<160> parts;
};

struct _MagicAnim_ {
   char* defName;
   char* name;
   int type;
};

#define o_ComboArtInfo (*(_ComboArtInfo_**)0x660B6C)
#define o_MagicAnim ((_MagicAnim_*)0x641E18)

_Spell_ spell[SPELLS_MAX];
_MagicAnim_ anim[ANIMS_MAX];
//char iniPath[MAX_PATH];

char spellIndirectTableA[] = {
   // Spells (starting from Quicksand #10)
    0,  1,  2,  2,  3,  4,  4,  4,  4,  4,
    5,  5,  5,  5,  4,  4,  4,  4,  4,  4,
    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
    6,  4,  4,  4,  4,  4,  4,  4,  4,  4,
    4,  4,  4,  4,  4,  4,  4,  4,  4,  5,
    4,  4,  4,  7,  8,  9, 10, 10, 10, 10,
   // Special Abilities (you cannot cast them anyway)
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
   -1,
   // New Spells (starting from Fear #81)
   4, 4, 4, 4, 5, 4
};

char spellIndirectTableB[] = {
   // Spells (starting from Quicksand #10)
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
   10, 11, 12, 13, 14, 15, 16, 17, 17, 17,
   17, 17, 17, 17, 17, 18, 17, 19, 20, 20,
   21, 17, 17, 22, 17, 17, 17, 23, 17, 17,
   17, 17, 17, 17, 17, 17, 17,  7, 17, 24,
   17, 17, 17, 25, 26, 27, 28, 29, 30, 31,
   // Special Abilities
   32, 33, 34, 17, 17, 34, 37, 37, 35, 37,
   36,
   // New Spells (starting from Fear #81)
   17, 17, 17, 17, 11, 17
};

char spellIndirectTableC[] = {
   // Spells (starting from Shield #27)
    0,  1,  2,  3,  4,  5,  6,  7, 32,  8,
   32, 32, 32, 32,  9, 10, 11, 12, 13, 14,
   32, 15, 16, 17, 18, 19, 20, 21, 22, 23,
   32, 24, 25, 26, 27, 28, 32, 32, 32, 32,
   32, 32, 32,
   // Special Abilities
   32, 29, 32, 30, 32, 31, -1, -1, -1, -1,
   -1,
   // New Spells (starting from Fear #81)
   32, 32, 32, 32, 32, 32
};

bool shrineSpells[SPELLS_MAX];

int __stdcall afterInit(LoHook* h, HookContext* c)
{
   // Spell Table
   for (int i = 0; i < SPL_FEAR_NEW; ++i)
      spell[i] = o_Spell[i];

   // Fear
   spell[SPL_FEAR_NEW].type = -1;
   spell[SPL_FEAR_NEW].wav_name = "FearRoE.wav";
   spell[SPL_FEAR_NEW].animation_ix = ANIM_FEAR_NEW;
   spell[SPL_FEAR_NEW].flags = 0x20415;
   spell[SPL_FEAR_NEW].name = "Fear";
   spell[SPL_FEAR_NEW].short_name = "Fear";
   spell[SPL_FEAR_NEW].level = 4;
   spell[SPL_FEAR_NEW].school_flags = 8;
   spell[SPL_FEAR_NEW].mana_cost[0] = 16;
   spell[SPL_FEAR_NEW].mana_cost[1] = 8;
   spell[SPL_FEAR_NEW].mana_cost[2] = 8;
   spell[SPL_FEAR_NEW].mana_cost[3] = 8;
   spell[SPL_FEAR_NEW].eff_power = 0;
   spell[SPL_FEAR_NEW].effect[0] = 75;
   spell[SPL_FEAR_NEW].effect[1] = 75;
   spell[SPL_FEAR_NEW].effect[2] = 50;
   spell[SPL_FEAR_NEW].effect[3] = 25;
   spell[SPL_FEAR_NEW].chance2get_var[0] = 10;
   spell[SPL_FEAR_NEW].chance2get_var[1] = 10;
   spell[SPL_FEAR_NEW].chance2get_var[2] = 10;
   spell[SPL_FEAR_NEW].chance2get_var[3] = 10;
   spell[SPL_FEAR_NEW].chance2get_var[4] = 10;
   spell[SPL_FEAR_NEW].chance2get_var[5] = 10;
   spell[SPL_FEAR_NEW].chance2get_var[6] = 10;
   spell[SPL_FEAR_NEW].chance2get_var[7] = 10;
   spell[SPL_FEAR_NEW].chance2get_var[8] = 10;
   spell[SPL_FEAR_NEW].ai_value[0] = 50;
   spell[SPL_FEAR_NEW].ai_value[1] = 50;
   spell[SPL_FEAR_NEW].ai_value[2] = 50;
   spell[SPL_FEAR_NEW].ai_value[3] = 50;
   spell[SPL_FEAR_NEW].description[0] =
      "{Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n";
   spell[SPL_FEAR_NEW].description[1] =
      "{Basic Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nSpell Point cost is half that of Normal Fear.\n";
   spell[SPL_FEAR_NEW].description[2] =
      "{Advanced Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is twice that of Basic Fear.\n";
   spell[SPL_FEAR_NEW].description[3] =
      "{Expert Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is three times that of Basic Fear.\n";

   // Poison
   spell[SPL_POISON_NEW].type = -1;
   spell[SPL_POISON_NEW].wav_name = "Poison.wav";
   spell[SPL_POISON_NEW].animation_ix = ANIM_POISON_NEW;
   spell[SPL_POISON_NEW].flags = 0x1015;
   spell[SPL_POISON_NEW].name = "Poison";
   spell[SPL_POISON_NEW].short_name = "Poison";
   spell[SPL_POISON_NEW].level = 4;
   spell[SPL_POISON_NEW].school_flags = 8;
   spell[SPL_POISON_NEW].mana_cost[0] = 20;
   spell[SPL_POISON_NEW].mana_cost[1] = 16;
   spell[SPL_POISON_NEW].mana_cost[2] = 16;
   spell[SPL_POISON_NEW].mana_cost[3] = 16;
   spell[SPL_POISON_NEW].eff_power = 0;
   spell[SPL_POISON_NEW].effect[0] = 0;
   spell[SPL_POISON_NEW].effect[1] = 0;
   spell[SPL_POISON_NEW].effect[2] = 0;
   spell[SPL_POISON_NEW].effect[3] = 0;
   spell[SPL_POISON_NEW].chance2get_var[0] = 10;
   spell[SPL_POISON_NEW].chance2get_var[1] = 10;
   spell[SPL_POISON_NEW].chance2get_var[2] = 10;
   spell[SPL_POISON_NEW].chance2get_var[3] = 10;
   spell[SPL_POISON_NEW].chance2get_var[4] = 10;
   spell[SPL_POISON_NEW].chance2get_var[5] = 10;
   spell[SPL_POISON_NEW].chance2get_var[6] = 10;
   spell[SPL_POISON_NEW].chance2get_var[7] = 10;
   spell[SPL_POISON_NEW].chance2get_var[8] = 10;
   spell[SPL_POISON_NEW].ai_value[0] = 50;
   spell[SPL_POISON_NEW].ai_value[1] = 50;
   spell[SPL_POISON_NEW].ai_value[2] = 50;
   spell[SPL_POISON_NEW].ai_value[3] = 50;
   spell[SPL_POISON_NEW].description[0] =
      "{Poison}\n\nPoison Description.\n";
   spell[SPL_POISON_NEW].description[1] =
      "{Basic Poison}\n\nBasic Poison Description.\n";
   spell[SPL_POISON_NEW].description[2] =
      "{Advanced Poison}\n\nAdvanced Poison Description.\n";
   spell[SPL_POISON_NEW].description[3] =
      "{Expert Poison}\n\nExpert Poison Description.\n";

   // Disease
   spell[SPL_DISEASE_NEW].type = -1;
   spell[SPL_DISEASE_NEW].wav_name = "Disease.wav";
   spell[SPL_DISEASE_NEW].animation_ix = ANIM_DISEASE_NEW;
   spell[SPL_DISEASE_NEW].flags = 0x1015;
   spell[SPL_DISEASE_NEW].name = "Disease";
   spell[SPL_DISEASE_NEW].short_name = "Disease";
   spell[SPL_DISEASE_NEW].level = 4;
   spell[SPL_DISEASE_NEW].school_flags = 8;
   spell[SPL_DISEASE_NEW].mana_cost[0] = 16;
   spell[SPL_DISEASE_NEW].mana_cost[1] = 12;
   spell[SPL_DISEASE_NEW].mana_cost[2] = 12;
   spell[SPL_DISEASE_NEW].mana_cost[3] = 12;
   spell[SPL_DISEASE_NEW].eff_power = 0;
   spell[SPL_DISEASE_NEW].effect[0] = 0;
   spell[SPL_DISEASE_NEW].effect[1] = 0;
   spell[SPL_DISEASE_NEW].effect[2] = 0;
   spell[SPL_DISEASE_NEW].effect[3] = 0;
   spell[SPL_DISEASE_NEW].chance2get_var[0] = 10;
   spell[SPL_DISEASE_NEW].chance2get_var[1] = 10;
   spell[SPL_DISEASE_NEW].chance2get_var[2] = 10;
   spell[SPL_DISEASE_NEW].chance2get_var[3] = 10;
   spell[SPL_DISEASE_NEW].chance2get_var[4] = 10;
   spell[SPL_DISEASE_NEW].chance2get_var[5] = 10;
   spell[SPL_DISEASE_NEW].chance2get_var[6] = 10;
   spell[SPL_DISEASE_NEW].chance2get_var[7] = 10;
   spell[SPL_DISEASE_NEW].chance2get_var[8] = 10;
   spell[SPL_DISEASE_NEW].ai_value[0] = 50;
   spell[SPL_DISEASE_NEW].ai_value[1] = 50;
   spell[SPL_DISEASE_NEW].ai_value[2] = 50;
   spell[SPL_DISEASE_NEW].ai_value[3] = 50;
   spell[SPL_DISEASE_NEW].description[0] =
      "{Disease}\n\nDisease Description.\n";
   spell[SPL_DISEASE_NEW].description[1] =
      "{Basic Disease}\n\nBasic Disease Description.\n";
   spell[SPL_DISEASE_NEW].description[2] =
      "{Advanced Disease}\n\nAdvanced Disease Description.\n";
   spell[SPL_DISEASE_NEW].description[3] =
      "{Expert Disease}\n\nExpert Disease Description.\n";

   // Aging
   spell[SPL_AGING_NEW].type = -1;
   spell[SPL_AGING_NEW].wav_name = "Age.wav";
   spell[SPL_AGING_NEW].animation_ix = ANIM_AGING_NEW;
   spell[SPL_AGING_NEW].flags = 0x1015;
   spell[SPL_AGING_NEW].name = "Aging";
   spell[SPL_AGING_NEW].short_name = "Aging";
   spell[SPL_AGING_NEW].level = 5;
   spell[SPL_AGING_NEW].school_flags = 2;
   spell[SPL_AGING_NEW].mana_cost[0] = 25;
   spell[SPL_AGING_NEW].mana_cost[1] = 20;
   spell[SPL_AGING_NEW].mana_cost[2] = 20;
   spell[SPL_AGING_NEW].mana_cost[3] = 20;
   spell[SPL_AGING_NEW].eff_power = 0;
   spell[SPL_AGING_NEW].effect[0] = 0;
   spell[SPL_AGING_NEW].effect[1] = 0;
   spell[SPL_AGING_NEW].effect[2] = 0;
   spell[SPL_AGING_NEW].effect[3] = 0;
   spell[SPL_AGING_NEW].chance2get_var[0] = 10;
   spell[SPL_AGING_NEW].chance2get_var[1] = 10;
   spell[SPL_AGING_NEW].chance2get_var[2] = 10;
   spell[SPL_AGING_NEW].chance2get_var[3] = 10;
   spell[SPL_AGING_NEW].chance2get_var[4] = 10;
   spell[SPL_AGING_NEW].chance2get_var[5] = 10;
   spell[SPL_AGING_NEW].chance2get_var[6] = 10;
   spell[SPL_AGING_NEW].chance2get_var[7] = 10;
   spell[SPL_AGING_NEW].chance2get_var[8] = 10;
   spell[SPL_AGING_NEW].ai_value[0] = 50;
   spell[SPL_AGING_NEW].ai_value[1] = 50;
   spell[SPL_AGING_NEW].ai_value[2] = 50;
   spell[SPL_AGING_NEW].ai_value[3] = 50;
   spell[SPL_AGING_NEW].description[0] =
      "{Aging}\n\nAging Description.\n";
   spell[SPL_AGING_NEW].description[1] =
      "{Basic Aging}\n\nBasic Aging Description.\n";
   spell[SPL_AGING_NEW].description[2] =
      "{Advanced Aging}\n\nAdvanced Aging Description.\n";
   spell[SPL_AGING_NEW].description[3] =
      "{Expert Aging}\n\nExpert Aging Description.\n";

   // Death Cloud
   spell[SPL_DEATH_CLOUD_NEW].type = 0;
   spell[SPL_DEATH_CLOUD_NEW].wav_name = "Deathcld.wav";
   spell[SPL_DEATH_CLOUD_NEW].animation_ix = ANIM_DEATH_CLOUD_NEW;
   spell[SPL_DEATH_CLOUD_NEW].flags = 0x8281;
   spell[SPL_DEATH_CLOUD_NEW].name = "Death Cloud";
   spell[SPL_DEATH_CLOUD_NEW].short_name = "Death Cloud";
   spell[SPL_DEATH_CLOUD_NEW].level = 5;
   spell[SPL_DEATH_CLOUD_NEW].school_flags = 8;
   spell[SPL_DEATH_CLOUD_NEW].mana_cost[0] = 25;
   spell[SPL_DEATH_CLOUD_NEW].mana_cost[1] = 20;
   spell[SPL_DEATH_CLOUD_NEW].mana_cost[2] = 20;
   spell[SPL_DEATH_CLOUD_NEW].mana_cost[3] = 20;
   spell[SPL_DEATH_CLOUD_NEW].eff_power = 40;
   spell[SPL_DEATH_CLOUD_NEW].effect[0] = 30;
   spell[SPL_DEATH_CLOUD_NEW].effect[1] = 30;
   spell[SPL_DEATH_CLOUD_NEW].effect[2] = 60;
   spell[SPL_DEATH_CLOUD_NEW].effect[3] = 120;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[0] = 10;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[1] = 10;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[2] = 10;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[3] = 10;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[4] = 10;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[5] = 10;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[6] = 10;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[7] = 10;
   spell[SPL_DEATH_CLOUD_NEW].chance2get_var[8] = 10;
   spell[SPL_DEATH_CLOUD_NEW].ai_value[0] = 50;
   spell[SPL_DEATH_CLOUD_NEW].ai_value[1] = 50;
   spell[SPL_DEATH_CLOUD_NEW].ai_value[2] = 50;
   spell[SPL_DEATH_CLOUD_NEW].ai_value[3] = 50;
   spell[SPL_DEATH_CLOUD_NEW].description[0] =
      "{Death Cloud}\n\nDeath Cloud Description.\n";
   spell[SPL_DEATH_CLOUD_NEW].description[1] =
      "{Basic Death Cloud}\n\nBasic Death Cloud Description.\n";
   spell[SPL_DEATH_CLOUD_NEW].description[2] =
      "{Advanced Death Cloud}\n\nAdvanced Death Cloud Description.\n";
   spell[SPL_DEATH_CLOUD_NEW].description[3] =
      "{Expert Death Cloud}\n\nExpert Death Cloud Description.\n";

   // Death Blow
   spell[SPL_DEATH_BLOW_NEW].type = 1;
   spell[SPL_DEATH_BLOW_NEW].wav_name = "Deathblo.wav";
   spell[SPL_DEATH_BLOW_NEW].animation_ix = ANIM_DEATH_BLOW_NEW;
   spell[SPL_DEATH_BLOW_NEW].flags = 0x1015;
   spell[SPL_DEATH_BLOW_NEW].name = "Death Blow";
   spell[SPL_DEATH_BLOW_NEW].short_name = "Death Blow";
   spell[SPL_DEATH_BLOW_NEW].level = 5;
   spell[SPL_DEATH_BLOW_NEW].school_flags = 2;
   spell[SPL_DEATH_BLOW_NEW].mana_cost[0] = 25;
   spell[SPL_DEATH_BLOW_NEW].mana_cost[1] = 20;
   spell[SPL_DEATH_BLOW_NEW].mana_cost[2] = 20;
   spell[SPL_DEATH_BLOW_NEW].mana_cost[3] = 20;
   spell[SPL_DEATH_BLOW_NEW].eff_power = 0;
   spell[SPL_DEATH_BLOW_NEW].effect[0] = 0;
   spell[SPL_DEATH_BLOW_NEW].effect[1] = 0;
   spell[SPL_DEATH_BLOW_NEW].effect[2] = 0;
   spell[SPL_DEATH_BLOW_NEW].effect[3] = 0;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[0] = 10;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[1] = 10;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[2] = 10;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[3] = 10;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[4] = 10;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[5] = 10;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[6] = 10;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[7] = 10;
   spell[SPL_DEATH_BLOW_NEW].chance2get_var[8] = 10;
   spell[SPL_DEATH_BLOW_NEW].ai_value[0] = 50;
   spell[SPL_DEATH_BLOW_NEW].ai_value[1] = 50;
   spell[SPL_DEATH_BLOW_NEW].ai_value[2] = 50;
   spell[SPL_DEATH_BLOW_NEW].ai_value[3] = 50;
   spell[SPL_DEATH_BLOW_NEW].description[0] =
      "{Death Blow}\n\nDeath Blow Description.\n";
   spell[SPL_DEATH_BLOW_NEW].description[1] =
      "{Basic Death Blow}\n\nBasic Death Blow Description.\n";
   spell[SPL_DEATH_BLOW_NEW].description[2] =
      "{Advanced Death Blow}\n\nAdvanced Death Blow Description.\n";
   spell[SPL_DEATH_BLOW_NEW].description[3] =
      "{Expert Death Blow}\n\nExpert Death Blow Description.\n";

   _PI->WriteDword(0x687FA8, (int)&spell);

   // Magic Animation Table
   for (int i = 0; i < ANIM_FEAR_NEW; ++i)
      anim[i] = o_MagicAnim[i];

   // Fear
   anim[ANIM_FEAR_NEW].defName = "C07spE0.def";
   anim[ANIM_FEAR_NEW].name = "Fear";
   anim[ANIM_FEAR_NEW].type = 0x101;

   // Poison
   anim[ANIM_POISON_NEW].defName = "sp11_.def";
   anim[ANIM_POISON_NEW].name = "Poison";
   anim[ANIM_POISON_NEW].type = 1;

   // Disease
   anim[ANIM_DISEASE_NEW].defName = "sp05_.def";
   anim[ANIM_DISEASE_NEW].name = "Disease";
   anim[ANIM_DISEASE_NEW].type = 1;

   // Aging
   anim[ANIM_AGING_NEW].defName = "sp01_.def";
   anim[ANIM_AGING_NEW].name = "Aging";
   anim[ANIM_AGING_NEW].type = 1;

   // Death Cloud
   anim[ANIM_DEATH_CLOUD_NEW].defName = "sp04_.def";
   anim[ANIM_DEATH_CLOUD_NEW].name = "DeathCloud";
   anim[ANIM_DEATH_CLOUD_NEW].type = 1;

   // Death Blow
   anim[ANIM_DEATH_BLOW_NEW].defName = "sp03_.def";
   anim[ANIM_DEATH_BLOW_NEW].name = "DeathBlow";
   anim[ANIM_DEATH_BLOW_NEW].type = 1;

   int AnimAddrDefName[] = {0x43F77E, 0x43FB6A, 0x4963FB, 0x4965CF, 0x5A5036, 0x5A6B14, 0x5A7A74, 0x5A962C};
   int AnimAddrName[] = {0x4689C4, 0x49651A, 0x4966CD, 0x5A6D2D, 0x5A7B06};
   
   for (int i = 0; i < sizeof(AnimAddrDefName) / sizeof(int); ++i)
      _PI->WriteDword(AnimAddrDefName[i], (int)&anim->defName);

   for (int i = 0; i < sizeof(AnimAddrName) / sizeof(int); ++i)
      _PI->WriteDword(AnimAddrName[i], (int)&anim->name);

   _PI->WriteDword(0x43E503, (int)&anim->type);
   
   return EXEC_DEFAULT;
}

int __stdcall disableCreatureSpells(LoHook* h, HookContext* c)
{
   for (int i = SPL_STONE; i <= SPL_ACID_BREATH; ++i)
      o_GameMgr->disabled_shrines[i] = true;

   return EXEC_DEFAULT;
}

int __stdcall shrineSpellsInit(LoHook* h, HookContext* c)
{
   for (int i = SPL_STONE; i <= SPL_ACID_BREATH; ++i)
      o_GameMgr->disabled_shrines[i] = true;   
   
   memcpy(&shrineSpells, &o_GameMgr->disabled_shrines, sizeof(shrineSpells) / sizeof(bool));   

   c->return_address = 0x4C2641;
   return NO_EXEC_DEFAULT;
}

int __fastcall fillShrines(_GameMgr_* game, int unused_edx, int shrineFlags)
{
   int availSpellsNum = 0;

   for (int i = 0; i < SPELLS_NUM; ++i)
   {
      int lvl = o_Spell[i].level - 1;
      if (lvl < 5 && 1 << lvl & shrineFlags && o_Spell[i].school_flags && !shrineSpells[i])
         ++availSpellsNum;
   }

   int spell = 0;
   int chosenSpell = 0;

   if (availSpellsNum)
   {
      int rndSpell = Randint(0, availSpellsNum - 1);
     
      for (int i = 0; i < SPELLS_NUM; ++i)
      {
         int lvl = o_Spell[i].level - 1;
         if (lvl < 5 && 1 << lvl & shrineFlags && o_Spell[i].school_flags && !shrineSpells[i])
         {
            if (spell == rndSpell) break;
            ++spell;
         }
         ++chosenSpell;
      }
     
      shrineSpells[chosenSpell] = true;
   }
   else
   {
      spell = 0;
     
      for (int i = 0; i < SPELLS_NUM; ++i)
      {
         int lvl = o_Spell[i].level - 1;
         if (lvl < 5 && 1 << lvl & shrineFlags && o_Spell[i].school_flags && !game->disabled_shrines[i])
         {
            shrineSpells[i] = false;
            ++spell;
         }
      }
     
      chosenSpell = spell ? fillShrines(game, unused_edx, shrineFlags) : ID_NONE;
   }

   return chosenSpell; 
}

int __stdcall DeathCloud(LoHook* h, HookContext* c)
{
   if (c->edx == SPL_DEATH_CLOUD_NEW)
   {
      CALL_5(void, __thiscall, 0x5A4C80, o_BattleMgr, *(int*)(c->ebp + 0xC), SPL_DEATH_CLOUD_NEW, c->esi, *(int*)(c->ebp + 0x1C));
   
      c->return_address = 0x5A2368;
      return NO_EXEC_DEFAULT;
   }

   return EXEC_DEFAULT;
}

void __fastcall updateSpellsFromArtifacts(_Hero_* hero)
{
   for (int iSpell = 0; iSpell < SPELLS_MAX; ++iSpell)
      if (hero->spell[iSpell] > 1) hero->spell[iSpell] = 0;

   for (int iSlot = 0; iSlot < 19; ++iSlot)
   {
      if (hero->doll_art[iSlot].id != ID_NONE)
      {
         if (hero->doll_art[iSlot].id == AID_SPELL_SCROLL)
         {
            if (hero->doll_art[iSlot].mod < SPELLS_NUM && !hero->spell[hero->doll_art[iSlot].mod])
               hero->spell[hero->doll_art[iSlot].mod] = 2;
         }
         else if (o_ArtInfo[hero->doll_art[iSlot].id].new_spell)
         {
            std::bitset<SPELLS_MAX> spells;
            CALL_2(int, __fastcall, 0x4D95C0, &spells, hero->doll_art[iSlot].id);

            for (std::size_t iSpell = 0; iSpell < spells.size(); ++iSpell)
            {
               if (spells[iSpell] && !hero->spell[iSpell])
                  hero->spell[iSpell] = 2;
            }

            int comboArtIndex = o_ArtInfo[hero->doll_art[iSlot].id].supercomposite;
            if (comboArtIndex != -1)
            {
               for (int iArt = 0; iArt < ARTIFACTS_NUM; ++iArt)
               {
                  if (o_ComboArtInfo[comboArtIndex].parts[iArt] && o_ArtInfo[iArt].new_spell)
                  {
                     std::bitset<SPELLS_MAX> spells;
                     CALL_2(int, __fastcall, 0x4D95C0, &spells, iArt);

                     for (std::size_t iSpell = 0; iSpell < spells.size(); ++iSpell)
                     {
                        if (spells[iSpell] && !hero->spell[iSpell])
                           hero->spell[iSpell] = 2;
                     }
                  }
               }
            }
         }
      }
   }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
   static bool plugin_On = false;
   if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
   {
      if ( !plugin_On )
      {
         plugin_On = true;
         _P = GetPatcher();
         _PI = _P->CreateInstance("HD.Plugin.H3.NewSpells");

         //GetCurrentDirectoryA(sizeof(iniPath), iniPath);
         //strcat(iniPath, "\\NewSpells.ini");

         // Moving and Expanding Spell Table
         _PI->WriteLoHook(0x4EE1C1, afterInit);
               
         // nwcthereisnospoon
         _PI->WriteByte (0x402902, SPELLS_NUM);

         // "(Already learned)" Text
         _PI->WriteDword(0x40D97C, 0x3EA);
         
         // AI
         _PI->WriteDword(0x41FBDF, 0x3EA);
         _PI->WriteByte (0x41FC91, SPELLS_NUM);
         _PI->WriteDword(0x425C72, 0x3EA);
         _PI->WriteDword(0x425E98, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x427039, 0x3EA);
         _PI->WriteDword(0x427044, 0x3EA);
         _PI->WriteByte (0x427085, SPELLS_NUM);
         _PI->WriteDword(0x4329C1, 0x3EA);
         _PI->WriteDword(0x432A43, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x432CDE, 0x3EA);
         _PI->WriteDword(0x432D1E, SPELLS_NUM * sizeof(_Spell_));
         // ------------
         // Adventure AI
         // ------------
         _PI->WriteDword(0x430AE5, 0x3EA + SPL_DIMENSION_DOOR);
         _PI->WriteDword(0x4E57CC, 0x3EA + SPL_SUMMON_BOAT);
         _PI->WriteDword(0x56B346, 0x3EA + SPL_TOWN_PORTAL);
         _PI->WriteDword(0x56B7EA, 0x3EA + SPL_DIMENSION_DOOR);
         _PI->WriteDword(0x56B93F, 0x3EA + SPL_FLY);
         _PI->WriteDword(0x56B99A, 0x3EA + SPL_WATER_WALK);
         // Battle AI
         _PI->WriteDword(0x43C6F2, SPELLS_NUM * sizeof(_Spell_));
         // Master Genie AI Spell Weighting
         _PI->WriteDword(0x43C21B, SPELLS_NUM * sizeof(_Spell_));
         // AI Quick Battle
         _PI->WriteDword(0x433026, 0x3EA);
         _PI->WriteDword(0x433719, 0x3EA);
         _PI->WriteDword(0x43940C, 0x3EA);
         _PI->WriteDword(0x43C561, 0x3EA);
         // AI Spell Scrolls?
         _PI->WriteDword(0x52A97A, 0x3EA);
         _PI->WriteDword(0x52A9B6, SPELLS_NUM * sizeof(_Spell_));
         
         // Can cast?
         _PI->WriteDword(0x447551, SPELLS_NUM * sizeof(_Spell_));
         
         _PI->WriteDword(0x447C7D, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x447CC8, SPELLS_NUM * sizeof(_Spell_));
         
         // Cheats in battle
         _PI->WriteByte (0x471C57, SPELLS_NUM);
         
         // Clear _Hero_.spell[140] (optional)
         _PI->WriteDword(0x48647A, 0x23);
         _PI->WriteJmp  (0x486485, 0x486498);
         
         _PI->WriteByte (0x4864B0, SPELLS_NUM);
         
         // Load Game?
         _PI->WriteByte (0x48A34B, SPELLS_NUM);
         
         // Scholar Secondary Skill
         _PI->WriteByte (0x4A2743, SPELLS_NUM);

         // New Game?
         _PI->WriteByte (0x4C244D, SPELLS_NUM);
         _PI->WriteByte (0x4C246F, SPELLS_NUM);
         _PI->WriteDword(0x4C24C9, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteByte (0x4C250E, SPELLS_NUM);
         _PI->WriteDword(0x4C2557, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x4C260D, SPELLS_NUM * sizeof(_Spell_));

         _PI->WriteByte (0x4E67AC, SPELLS_NUM);
         
         // Cheat Menu?
         _PI->WriteByte (0x4F508B, SPELLS_NUM);
         _PI->WriteDword(0x4F50CE, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x4F5114, SPELLS_NUM * sizeof(_Spell_));
                           
         // Pyramids
         _PI->WriteByte (0x4C170D, SPELLS_NUM);
                 
         // Shrines
         _PI->WriteDword(0x4C92C5, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x4C9347, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x4C93C0, SPELLS_NUM * sizeof(_Spell_));
         
         _PI->WriteByte (0x4CEC4F, SPELLS_NUM);
         
         // Clear _Hero_.spell[140] (optional)
         _PI->WriteDword(0x4D8F2E, 0x23);
         _PI->WriteJmp  (0x4D8F36, 0x4D8F49);
         
         _PI->WriteByte (0x4D8F53, SPELLS_NUM);
         _PI->WriteByte (0x4D8F8A, SPELLS_NUM);
         
         // Tome of Air Magic
         _PI->WriteDword(0x4D962D, SPELLS_NUM * sizeof(_Spell_));
         // Tome of Fire Magic
         _PI->WriteDword(0x4D9681, SPELLS_NUM * sizeof(_Spell_));
         // Tome of Water Magic
         _PI->WriteDword(0x4D96D6, SPELLS_NUM * sizeof(_Spell_));
         // Tome of Earth Magic
         _PI->WriteDword(0x4D972E, SPELLS_NUM * sizeof(_Spell_));
         // Spellbinder's Hat
         _PI->WriteDword(0x4D9771, SPELLS_NUM * sizeof(_Spell_));
         
         // Scholars
         _PI->WriteByte (0x5012B7, SPELLS_NUM);
         
         _PI->WriteDword(0x527ACB, 0x3EA);
         _PI->WriteDword(0x527B08, SPELLS_NUM * sizeof(_Spell_));

         // RMG
         _PI->WriteDword(0x534C4B, SPELLS_NUM * sizeof(_Spell_));
         
         // RMG Spell Scrolls
         _PI->WriteDword(0x5353D5, SPELLS_NUM);
         _PI->WriteByte (0x53542B, SPELLS_NUM);
         
         // Spell Book
         _PI->WriteDword(0x59CD5E, 0x3EA);
         _PI->WriteDword(0x59CDBF, SPELLS_NUM * sizeof(_Spell_));

         // Cast Spell
         _PI->WriteDword(0x5A1AD6, SPELLS_NUM * sizeof(_Spell_));

         // Mage Guild
         _PI->WriteByte (0x5BEA2C, SPELLS_NUM);
         _PI->WriteByte (0x5BEA70, SPELLS_NUM);
         _PI->WriteByte (0x5BEAAD, SPELLS_NUM);
         _PI->WriteDword(0x5BEAFE, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x5BEB2C, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteByte (0x5BEB48, SPELLS_NUM);
         _PI->WriteByte (0x5BEB71, SPELLS_NUM);
         _PI->WriteByte (0x5BEBB2, SPELLS_NUM);
         _PI->WriteDword(0x5BEC05, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteByte (0x5BEC1B, SPELLS_NUM);
                 
         // Conflux Grail
         _PI->WriteDword(0x5BE512, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x5BE56E, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x5D7464, SPELLS_NUM);
         
         // ---------------------------
         // New _Hero_.spell[140] field
         // ---------------------------
         _PI->WriteCodePatch(0x4D8B72, "%n", 8);
         _PI->WriteCodePatch(0x4D8F7F, "%n", 8);
         _PI->WriteCodePatch(0x4D95AF, "%n", 7);

         // ----------------------------------------
         // New _GameMgr_.disabled_spells[140] field
         // ----------------------------------------
         _PI->WriteByte(0x4C16ED, 4); // Pyramids
         _PI->WriteByte(0x4C254C, 4); // Titan's Lightning Bolt
         _PI->WriteByte(0x4C25F1, 4); // Titan's Lightning Bolt
         _PI->WriteByte(0x501297, 4); // Scholars
         _PI->WriteByte(0x5BEA55, 4); // Mage Guild
                         
         _PI->WriteDword(0x52AE1C, 0x3EA);

         // ------
         // Battle
         // ------
         _PI->WriteDword(0x43E3DF, SPELLS_NUM);
         _PI->WriteByte (0x443F63, SPELLS_NUM);
         _PI->WriteByte (0x446F03, SPELLS_NUM);
         _PI->WriteByte (0x4963E9, ANIMS_NUM);
         _PI->WriteByte (0x4965BD, ANIMS_NUM);
         _PI->WriteByte (0x502405, SPELLS_NUM);
         _PI->WriteByte (0x502451, SPELLS_NUM);
         _PI->WriteByte (0x5024CF, SPELLS_NUM);
         _PI->WriteByte (0x502515, SPELLS_NUM);
         _PI->WriteByte (0x502E62, SPELLS_NUM);
         _PI->WriteByte (0x502EB7, SPELLS_NUM);
         _PI->WriteByte (0x59EFD9, SPELLS_NUM - 1 - ADVSPELLS_NUM);
         _PI->WriteDword(0x59EFE4, (int)&spellIndirectTableA);
         _PI->WriteByte (0x5A064E, SPELLS_NUM - 1 - ADVSPELLS_NUM);
         _PI->WriteDword(0x5A0659, (int)&spellIndirectTableB);
         //_PI->WriteDword(0x4446FD, (int)&spellIndirectTableC);
                 
         // --------------------------------------------------
         // New _BattleStack_.active_spell_duration[162] field
         // --------------------------------------------------
         _PI->WriteCodePatch(0x4446D2, "%n", 7);
         _PI->WriteJmp  (0x444694, 0x4450C2);
         
         // Disable creature spells
         _PI->WriteLoHook(0x4C2567, disableCreatureSpells);

         // Shrine Spells
         _PI->WriteLoHook(0x4C2625, shrineSpellsInit);
         _PI->WriteHiHook(0x4C9260, SPLICE_, DIRECT_, THISCALL_, fillShrines);
         
         // Death Cloud
         _PI->WriteLoHook(0x5A0F4C, DeathCloud);

         // Artifacts (incl. Spell Scrolls);
         _PI->WriteHiHook(0x4D9840, SPLICE_, DIRECT_, THISCALL_, updateSpellsFromArtifacts);
      }
   }

   return TRUE;
}

* * *
Как-то не обращал раньше внимания: градации цвета прямоугольника с числом воинов в отряде - это фишка HD мода? Вроде, в оригинале был только зелёный, красный и жёлтый для положительных, отрицательных и смешанных эффектов соответственно.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 24 авг 2021, 08:10

AlexSpl писал(а):

Думаю, как добавлю адреса из MoP, многое заработает :smile2: Я только переживаю за active_spells_power[]. Так не хочется переносить... Представляю, как больно было переписывать функцию updateSpellsFromArtifacts(). Попробуй потом разберись в коде на asm, а на C++ через битсеты - всё красиво и понятно.

Я так понял, что Вы хотите что-то придумать для active_spells_power[], чтобы его не переносить. Да уж, если ничего не получится придумать, то придется переносить... А в таком случае, как я понял, придется переписывать еще и функцию updateSpellsFromArtifacts(), верно? В MoP, я так понял, она уже переписана.

AlexSpl писал(а):

:?: Такой вопрос: зачем тогда игре хранить уровень школы магии наложенного заклинания вместе с его длительностью? Есть предположения? И нельзя ли использовать active_spells_power как продолжение active_spell_duration, что избавило бы от дополнительных хуков и, самое главное, потенциальных ошибок?

Хороший вопрос. Я честно говоря без понятия.

AlexSpl писал(а):

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

Ну так с модом теже 3 цвета (зеленый, красный и желтый) и остались. Вроде, нет никаких градаций.
Вернуться к началу

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: Как создать плагин для HD мода

Сообщение AlexSpl » 24 авг 2021, 09:52

А Вы присмотритесь: когда на стеке и положительные, и отрицательные эффекты, то чем больше отрицательных эффектов, тем цвет ближе к красному, а чем больше положительных - к зелёному. Я сам удивился.

Цитата:
Я так понял, что Вы хотите что-то придумать для active_spells_power[], чтобы его не переносить. Да уж, если ничего не получится придумать, то придется переносить... А в таком случае, как я понял, придется переписывать еще и функцию updateSpellsFromArtifacts(), верно? В MoP, я так понял, она уже переписана.

Функция уже переписана. Если переносить, то это хук на каждую инструкцию, которая работает с полями, чего очень не хочется.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 24 авг 2021, 10:04

AlexSpl писал(а):

А Вы присмотритесь: когда на стеке и положительные, и отрицательные эффекты, то чем больше отрицательных эффектов, тем цвет ближе к красному, а чем больше положительных - к зелёному. Я сам удивился.

Да, действительно, Вы правы, так и есть. Я это только и заметил. Раньше как-то не обращал на это внимание.

AlexSpl писал(а):

Функция уже переписана. Если переносить, то это хук на каждую инструкцию, которая работает с полями, чего очень не хочется.

А как в MoP обстоят дела с этим? Может, как там сделать?
Вернуться к началу

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: Как создать плагин для HD мода

Сообщение AlexSpl » 24 авг 2021, 10:12

Цитата:
А как в MoP обстоят дела с этим? Может, как там сделать?

В MoP вообще всё переносится. Но я считаю, что если игра не работает с полем, то его можно использовать. Например, массив disabled_shrines[] используется в качестве временного при генерации заклов в святилищах. Почему бы не расширить за счёт него массив disabled_spells[]? Аналогичное я хочу провернуть и с массивом active_spells_power[]. Вот в упор не вижу, зачем он вообще нужен, и пока известный мне код подтверждает, что он не используется, но я ещё не всё смотрел и брейкпоинты на чтение/запись не ставил.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 24 авг 2021, 10:22

Я Вас понял. Вы ищите массивы, которые используються временно или вообще не используется и используете их, чтобы не переносить все. Надеюсь, у Вас все получится.
Вернуться к началу

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: Как создать плагин для HD мода

Сообщение AlexSpl » 24 авг 2021, 10:27

Цитата:
Я Вас понял. Вы ищите массивы, которые используються временно или вообще не используется и используете их, чтобы не переносить все. Надеюсь, у Вас все получится.

Да. И отличный пример: объединение массива выученных героем заклинаний и массива тех, которые он знает временно (пока носит свиток или арт). Ну, если с active_spells_power[] не кейс, то, конечно, придётся переносить, но я буду до последнего за объединение.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 24 авг 2021, 13:18

Кстати, с заклами, повторяющими абилки, сложно ли будет сделать так, чтобы не дублировать картинку, когда на один отряд наложен одинаковый закл и абилка, а только обновлять кол-во раундов действия этого закла на максимальное?

Я предлагаю, как писал ранее, в подобных случаях оставлять одну картинку и просто обновлять длительность раундов этого закла всегда выбирая большее. Например, на отряде один из таких заклов (Disease, Poison или Aging) и атакующий отряд накладывает такой же (свою абилку). В таком случае мы обновляем только длительность этого закла при необходимости. То есть кол-во раундов действия этого закла устанавливаем в max(СМ - x, 3), где x от 0 до СМ. И наооборот, когда на отряде абилка и на этот отряд кастуется повторяющий эту абилку закл, то тогда кол-во раундов устанавливаем следущее: max(3 - x, СМ), где x от 0 до 3. А картинка не дублируется и всегда одна. Сложно ли будет такое сделать?

***

Проверил, именно так, как я описал выше, и обстоят дела с Проклятием, Слепотой, Жаждой крови и другими заклами повторяющими абилки в оригинале. Хотя я и придумал это еще до проверки. Оказалось, оно так и есть. :smile1:
Вернуться к началу

Пред.След.

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

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

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

cron