Объявления

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

Шпаргалка для создателей плагинов

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5222
Зарегистрирован: 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)
Поблагодарили: 2027 раз.

Шпаргалка для создателей плагинов

Сообщение AlexSpl » 20 янв 2021, 20:29

В этой теме предлагаю делиться базовыми знаниями о том, как получить информацию о чём-то, имея другую информацию. Например, как получить указатель на структуру/объект по указателю на другую структуру/объект, координатам, номеру игрока и т.п., а также кодом, который умеет делать неочевидные, но полезные вещи. Эта тема не замена heroes3f.idb, homm3.h, H3API и т.д., поэтому описывать, как получить что-то внутри структуры/объекта, не нужно. Идея в том, чтобы делиться тем, что однажды пригодилось при создании плагина, но что вы долго искали/реверсили. Также предлагаю редактировать свои посты, дополняя их информацией, а не создавать новые. Я пока начну только с одного примера, но, может быть, у кого-то их много и он/она захочет ими поделиться. Итак :smile1:

* * *

1. Карта приключений и объекты на ней

:?: Как получить указатель на состояние банка существ по указателю на структуру клетки карты, являющуюся входом в банк существ :?:
Код: Выделить всё
_MapItem_* mapItem;
_CrBankState_* bankState = CALL_1(_CrBankState_*, __fastcall, 0x405D80, mapItem);


:?: Как получить указатель на состояние жилища существ по указателю на структуру клетки карты, являющуюся входом в жилище существ :?:
(Спасибо: igrik)
Код: Выделить всё
// Получаем указатель на _Dwelling_ по ID жилища существ
_Dwelling_* GetDwelling(_int_ dwellingId) {
    return (_Dwelling_ *)(o_GameMgr->Field<int>(0x4E39C) + 92 * dwellingId);
}

// Получаем состояние жилища существ
_Dwelling_* dwelling = GetDwelling(mapItem->setup);

:?: Как получить координаты x, y, z клетки карты по указателю на структуру клетки карты :?:
(Спасибо: RoseKavalier)
Код: Выделить всё
int mapSize = o_AdvMgr->map->size;
int pos = mapItem - o_AdvMgr->map->items;
char x = pos % mapSize;
pos /= mapSize;
char y = pos % mapSize;
char z = pos / mapSize;

2. Города и замки

:?: Как получить тип стартового замка игрока по номеру игрока :?:
Код: Выделить всё
int playerID;
const int startTownType = o_GameMgr->Field<int>(0x1F6A0 + 0x10 + playerID * 4);

3. Герои, их свойства и характеристики

:?: Как получить номер стартового героя игрока по номеру игрока :?:
Код: Выделить всё
int playerID;
const int startHeroID = o_GameMgr->Field<int>(0x1F6A0 + 0x1A4 + playerID * 4);

:?: Как получить модификаторы (множители) вторичных навыков героя с учётом его специализации и экипированных артефактов по указателю на структуру героя :?:
Код: Выделить всё
_Hero_* hero;
bool clamp_value; // Нужна для Некроматии: true - модификатор ограничен числом 1.0, false - модификатор не ограничен
float ArcheryMod = CALL_1(float, __thiscall, 0x4E43D0, hero); // Стрельба (Archery)
float DiplomacyMod = CALL_1(float, __thiscall, 0x4E47F0, hero); // Дипломатия (Diplomacy)
float EagleEyeMod = CALL_1(float, __thiscall, 0x4E4690, hero); // Зоркость (Eagle Eye)
float NecromancyMod = CALL_2(float, __thiscall, 0x4E3F40, hero, clamp_value); // Некромантия (Necromancy)
float EstatesMod = CALL_1(float, __thiscall, 0x4E4600, hero); // Имущество (Estates)
float LearningMod = CALL_1(float, __thiscall, 0x4E4AB0, hero); // Обучение (Learning)
float OffenseMod = CALL_1(float, __thiscall, 0x4E4520, hero); // Нападение (Offense)
float ArmorerMod = CALL_1(float, __thiscall, 0x4E4580, hero); // Доспехи (Armorer)
float IntelligenceMod = CALL_1(float, __thiscall, 0x4E4B20, hero); // Интеллект (Intelligence)
float ResistanceMod = CALL_1(float, __thiscall, 0x4E4950, hero); // Сопротивление (Resistance)
float FirstAidMod = CALL_1(float, __thiscall, 0x4E4B90, hero); // Первая помощь (First Aid)

:?: Как получить радиус обзора героя :?:
Код: Выделить всё
_Hero_* hero;
int ScoutingRadius = CALL_1(int, __thiscall, 0x4E42E0, hero);

4. Бой

:?: Как получить номер текущего раунда :?: (Требует проверки)
Код: Выделить всё
int currentRound = o_BattleMgr->Field<int>(0x132A0) - 30000;

:?: Как получить текущую скорость отряда :?:
Код: Выделить всё
_BattleStack_* battleStack;
int speed = CALL_1(int, __thiscall, 0x4489F0, battleStack);

5. Графика, анимация и звук

:?: Как отметить отряды для анимации массового заклинания :?:
Код: Выделить всё
#define AnimateStack (((bool(*)[20])&o_BattleMgr->Field<bool>(0x547C)))

memset(AnimateStack, false, 40);

// Отмечаем отряды, для которых необходима анимация (в цикле)
AnimateStack[side][stackID] = true;

// Проигрываем массовую анимацию
CALL_4(void, __thiscall, 0x5A6AD0, o_BattleMgr, AnimateStack, o_Spell[spellId].animation_ix, 0);

To be continued...
Последний раз редактировалось AlexSpl 14 мар 2021, 23:49, всего редактировалось 9 раз(а).
Вернуться к началу

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

Re: Шпаргалка для создателей плагинов

Сообщение RoseKavalier » 21 янв 2021, 01:03

Good initiative! Hopefully it can expand on the encyclopediastarted by Ben80.

AlexSpl писал(а):

3. Герои, их свойства и характеристики

:?: Как получить модификаторы (множители) вторичных навыков героя с учётом его специализации и экипированных артефактов по указателю на структуру героя :?:
Код: Выделить всё
float NecromancyMod = CALL_1(float, __thiscall, 0x4E3F40, hero); // Некромантия (Necromancy)

Function prototype for necromancy takes an additional parameter:
Код: Выделить всё
/**
 * @brief Calculates the hero's necromancy power
 *
 * @param clamp_value Whether to cap the value at 1.0f
 * @return Percentage of creatures to raise
 */
_H3API_ FLOAT H3Hero::GetNecromancyPower(bool clamp_value) const
{
   return THISCALL_2(FLOAT, 0x4E3F40, this, clamp_value);
}


:?: A few more hero functions :?:
Код: Выделить всё
/**
 * @brief How many gold is generated by hero
 * Considers both estates and gold specialty
 *
 * @return The amount of gold to generate
 */
_H3API_ INT32 H3Hero::GetGeneratedGold() const
{
    return THISCALL_1(INT32, 0x4E4600, this);
}
/**
 * @brief Calculates how many mana points to restore daily
 * Considers mysticism and artifacts worn
 *
 * @return The amount of spell points that will be restored
 */
_H3API_ INT32 H3Hero::GetSpellPointsRestored() const
{
   return THISCALL_1(INT32, 0x4E41B0, this);
}
/**
 * @brief Calculate the hero's total luck
 *
 * @param enemy_hero Can be nullptr if no enemy
 * @param is_cursed_ground Whether the hero is on cursed ground
 * @param clamp_value Whether to clamp the value between -3..+3
 * @return Total luck under specified conditions
 */
_H3API_ INT32 H3Hero::GetLuckBonus(H3Hero* enemy_hero, bool is_cursed_ground, bool clamp_value) const
{
   return THISCALL_4(INT32, 0x4E3930, this, enemy_hero, is_cursed_ground, clamp_value);
}
/**
 * @brief Calculate the hero's total morale
 *
 * @param enemy_hero *UNUSED* Can be nullptr if no enemy
 * @param is_cursed_ground Whether the hero is on cursed ground
 * @param clamp_value Whether to clamp the value between -3..+3
 * @return Total morale under specified conditions
 */
_H3API_ INT32 H3Hero::GetMoraleBonus(H3Hero* enemy_hero, bool is_cursed_ground, bool clamp_value) const
{
   return THISCALL_4(INT32, 0x4E3C20, this, enemy_hero, is_cursed_ground, clamp_value);
}
Вернуться к началу


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

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

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

cron