Так, ввиду того, что пост XEPOMAHT'a обрезается (первый пост в этой странице) - размещу ещё раз.
Полностью! разобранные структуры Героя, Битвы и Стека
PHP Code:
NOALIGN struct _Hero_: _Struct_ { _int16_ x; // +0 _int16_ y; // +2 _int16_ z; // +4 _byte_ visible; // +6 _dword_ mui_xyz; // +7 _byte_ miu_is; // +11 // miu = map_item under hero _dword_ miu_object_type; // +12 _dword_ miu_object_c_flag; // +16 _dword_ miu_UnderHero; // +20 _word_ spell_points; // +24 _dword_ id; // +26 _dword_ id_wtf; // +30 _int8_ owner_id; // +34 _char_ name[13]; // +35 _dword_ _class; // +48 _byte_ pic; // +52 _dword_ targetX; // +53 _dword_ targetY; // +57 _dword_ targetZ; // +61 _word_ last_magic_school_level; // +65 _byte_ target_is_critical; // +67 _byte_ patrol_x; // +68 _byte_ patrol_y; // +69 _byte_ patrolRadius; // +70 _byte_ facing; // +71 _byte_ flags; // +72 _dword_ movement_max; // +73 _dword_ movement_curr; // +77 _dword_ expa; // +81 _word_ level; // +85 _dword_ visited[10]; // +87 (0-learningStones, 1-marlettoTower, 2-gardenRevelation, 3-mercenaryCamp, 4-starAxis, 5-treeKnowldge, 6-libraryEnlightenment, 7-arena, 8-schoolMagic, 9-schoolWar) _dword_ shrineFlags[4]; // +127 _byte_ levelSeed; // +143 _byte_ lastWisdom; // +144 _Army_ army; // +145 _byte_ second_skill[28]; // +201 _byte_ second_skill_show[28]; // +229 // secSkillPosition[28] _dword_ second_skill_count; // +257 _dword_ temp_mod_flags; // + 261 // _HeroFlags_ temp_mod_flags; // + 261 float turnExperienceToRVRatio; // +265 _byte_ dd_cast_this_turn; // +269 _int32_ disguise_cast_power; // +270 _int32_ fly_cast_power; // +274 _int32_ waterwalk_cast_power; // +278 _byte_ moraleBonus; // +282 _byte_ luckBonus; // +283 _byte_ is_sleeping; // +284 _int32_ bounty; // +285 _byte_ TownSpecialGrantedMask[8]; // +289 std::bitset<48> TownSpecialGrantedMask; _int32_ VisionsPower; // +297 _Artifact_ doll_art[19]; // +301 _byte_ free_add_slots; // +453 _byte_ locked_slot[14]; // +454 _Artifact_ backpack_art[64]; // +468 _byte_ backpack_arts_count; // +980 _dword_ female; // +981 _bool8_ is_castom_biography; // +985 _HStringF_ biography; // +986 std::string biography; _byte_ spells_spellbook[70]; // +1002 _byte_ spells_available[70]; // +1072 _byte_ primary_skill[4]; // +1142 _int32_ aggression; // +1146 _int32_ value_of_power; // +1150 _int32_ value_of_duration; // +1154 _int32_ value_of_knowledge; // +1158 _int32_ value_of_spring; // +1162 _int32_ value_of_well; // +1166
// normal void Hide() {CALL_1(void, __thiscall, 0x4D7950, this);} void Show(_int_ mapitem_type, _int_ mapitem_setup) {CALL_3(void, __thiscall, 0x4D7840, this, mapitem_type, mapitem_setup);} char* Get_className() {return CALL_1(char*, __thiscall, 0x4D91E0, this);} int GetLandModifierUnder() {return CALL_1(int, __thiscall, 0x4E5210, this);} void CastFly(int powerCast) {CALL_2(void, __thiscall, 0x4E5C10, this, powerCast);}
// телепортировать героя _byte_ Teleport(_dword_ xyz) { return CALL_6(_byte_, __thiscall, 0x41DAB0, o_AdvMgr, this, xyz, 0, 1, 0); } // дать армию герою _bool_ AddStack(_int_ type, _int_ amount, _int_ slot = -1) { return CALL_4(_bool_, __thiscall, 0x44A9B0, &this->army, type, amount, slot); }
// обучение грамотностью между героями void TeachScholar(_Hero_* heroRight) { CALL_2(void, __fastcall, 0x4A25B0, this, heroRight); }
void GiveArtifact(_Artifact_* art, int is_need_build_combo, int check_win_game) {CALL_4(void, __thiscall, 0x4E32E0, this, art, is_need_build_combo, check_win_game);} void GiveArtifact(_int_ art_id, int is_need_build_combo, int check_win_game) { _Artifact_ art; art.id = art_id; art.mod = 0xFFFF; GiveArtifact(&art, is_need_build_combo, check_win_game); }
_bool_ DoesHasArtifact(int art_id) {return CALL_2(_bool_, __thiscall, 0x4D9420, this, art_id);} _bool_ DoesWearArtifact(int art_id) {return CALL_2(_bool_, __thiscall, 0x4D9460, this, art_id);} void RemoveBattleMachine(int creature_id) {CALL_2(void, __thiscall, 0x4D94D0, this, creature_id);} int RemoveDollArtifact(int doll_slot_index) {return CALL_2(int, __thiscall, 0x4E2E40, this, doll_slot_index);} int AddDollArtifact(_Artifact_* art, int doll_slot_index) {return CALL_3(int, __thiscall, 0x4E2C70, this, art, doll_slot_index);} int RemoveBackpackArtifact(int index) {return CALL_2(int, __thiscall, 0x4E2FC0, this, index);} int AddBackpackArtifact(_Artifact_* art, int index) {return CALL_3(int, __thiscall, 0x4E3200, this, art, index);}
// открытие окна героя _int_ ShowHeroScreen(_int_ noDissmiss, _int_ noRedrawAdvMap, _byte_ rightClickDlg) { return CALL_4(_int_, __fastcall, 0x4E1A70, this->id, noDissmiss, noRedrawAdvMap, rightClickDlg); }
// получить стоимость маны за заклинание _int_ GetSpellCost(_int_ spell_id, _Army_* army, _int_ land_modifier) { return CALL_4(_int_, __thiscall, 0x4E54B0, this, spell_id, army, land_modifier); }
// Получение уровня силы магии в бою _int_ Get_School_Level_Of_Spell(_int_ spell_id, _int_ land_modifier) { return CALL_3(_int_, __thiscall, 0x4E52F0, this, spell_id, land_modifier); }
// Получение силы спелла от бонуса артов (длительность действия) _int_ Get_Spell_Rounds_Bonus_Arts() { return CALL_1(_int_, __thiscall, 0x4E5020, this); } // Получение силы спелла от бонуса втор.навыка Волшебство _int64_ Get_Spell_Power_Bonus_Arts_And_Sorcery(int spell, signed int damage, _BattleStack_* stack) { return CALL_4(_int64_, __thiscall, 0x4E59D0, this, spell, damage, stack); }
// Получение бонуса к эффекту заклинания за специализацию. _int_ GetSpell_Specialisation_PowerBonuses(int Spell_id, signed int damage, int Creature_level) { return CALL_4(_int_, __thiscall, 0x4E6260, this, Spell_id, Creature_level, damage); }
_int_ GetSpecialTerrain() {return CALL_1(_int_, __thiscall, 0x4E5130, this); }
// СПЕЦИАЛИЗАЦИИ ГЕРОЕВ // float SS_GetArcheryPower = CALL_1(float, __thiscall, 0x4E43D0, hero); // Стрельба (Archery) // float SS_GetDiplomacyPower = CALL_1(float, __thiscall, 0x4E47F0, hero); // Дипломатия (Diplomacy) // float SS_GetEagleEyePower = CALL_1(float, __thiscall, 0x4E4690, hero); // Зоркость (Eagle Eye) // float SS_GetNecromancyPower = CALL_1(float, __thiscall, 0x4E3F40, hero, _bool8_ isSetMaxValuePower); // Некромантия (Necromancy) // float SS_GetEstatesPower = CALL_1(float, __thiscall, 0x4E4600, hero); // Имущество (Estates) // float SS_GetLearningPower = CALL_1(float, __thiscall, 0x4E4AB0, hero); // Обучение (Learning) // float SS_GetOffensePower = CALL_1(float, __thiscall, 0x4E4520, hero); // Нападение (Offense) // float SS_GetArmorerPower = CALL_1(float, __thiscall, 0x4E4580, hero); // Доспехи (Armorer) // float SS_GetIntelligencePower = CALL_1(float, __thiscall, 0x4E4B20, hero); // Интеллект (Intelligence) // float SS_GetResistancePower = CALL_1(float, __thiscall, 0x4E4950, hero); // Сопротивление (Resistance) // float SS_GetFirstAidPower = CALL_1(float, __thiscall, 0x4E4B90, hero); // Первая помощь (First Aid) // _int_ SS_GetEstatesPower = CALL_1(_int_, __thiscall, 0x4E4600, hero); // Имущество // _int_ SS_GetMysticismPower = CALL_1(_int_, __thiscall, 0x4E41B0, hero); // Мистицизм // _int_ SS_GetScoutingRadius = CALL_1(_int_, __thiscall, 0x4E42E0, hero); // Разведка // _int_ ReCalculateMovementPoints = CALL_1(_int_, __thiscall, 0x4E4C00, hero, _bool8_ inOnBoat); // Пересчитать мувпоинты //my void ShowSpellBookDlg(int a1, int a2, int land_modifier) { if (this->doll_art[17].id != -1) { _Dlg_* dlg = (_Dlg_*)o_New(0xD0); // create spellbook dlg CALL_5(void, __thiscall, 0x59C0F0, dlg, this, a1, a2, land_modifier); dlg->Run(); // destroy spellbook dlg CALL_1(void, __thiscall, 0x59CBF0, dlg); o_Delete(dlg); } } void ShowSpellBookDlg(int a1, int a2) {ShowSpellBookDlg(a1, a2, this->GetLandModifierUnder());} };
PHP Code:
NOALIGN struct _BattleMgr_ : _Struct_ { _Manager_ mgr; // 0...56 _byte_ field_38[4]; // +56 (что-то из manager)
enum BATTLE_ACTION { BA_CANCEL, BA_HERO_CAST_SPELL, BA_WALK, BA_DEFEND, BA_RETREAT, BA_SURRENDER, BA_WALK_ATTACK, BA_SHOOT, BA_WAIT, BA_CATAPULT, BA_MONSTER_SPELL, BA_FIRST_AID_TENT, BA_NOTHING //12 = No action(can be to disable stack for this round) };
_int32_ action; // +60 (BG:A) _int32_ actionParam; // +64 _int32_ actionTarget; // +68 _int32_ actionParam2; // +72 _byte_ iLastDrawGridShade[187]; // +76 _byte_ iCurDrawGridShade[187]; // +263 _byte_ f_1C2[2]; // +450 (выравнивание) _BattleHex_ hex[187]; // +452 (112*187) _int32_ combatTerrain; // +21396 _int32_ combatFringe; // +21400 _int32_ iCombatCycleType; // +21404 _int32_ iElevationOverlay; // +21408 _bool32_ iDoorStatus; // +21412 _bool32_ bMoatOn; // +21416 _bool32_ moatIsWide; // +21420 _Pcx16_* saveScreenPreGrid; // +21424 (Bitmap16Bit*) _Pcx16_* saveScreenPostGrid; // +21428 _Pcx16_* combatMouseBackground; // +21432 _MapItem_* MapItem; // +21436 _int32_ special_Ground; // +21440 _bool8_ antiMagic_Garrison; // +21444 _bool8_ isBank; // +21445 _bool8_ f_53C6[2]; // +21446 (выравнивание) _Town_* town; // +21448 _Hero_* hero[2]; // +21452 _int32_ heroSpellPower[2]; // +21460 _bool32_ playDoh; // +21468 _bool32_ playYeah; // 21472 _int32_ heroFrameType[2]; // +21476 _int32_ heroFrameIndex[2]; // +21484 _int32_ heroDataSet[2]; // +21492 _dword_ heroLastFidgetTime[2]; // +21500 _Def_* heroDefLoaded[2]; // +21508 _Def_* heroFlagLoaded[2]; // +21516 _int32_ heroFlagCadre[2]; // +21524 _int32_ heroUpdateRect[2][4]; // +21532 _int32_ heroFlagUpdateRect[2][4]; // +21564 _List_<_int32_> EagleEyeSpellLearned[2]; // +21596 (H3Vector<INT32>) _byte_ armyEffected[2][20]; // +21668 _bool8_ isHuman[2]; // +21668 (isNotAI[2]) _bool8_ isLocalHuman[2]; // +21670 (isHuman[2]) _int32_ playerID[2]; // +21672 (owner_id[2]) _bool8_ hasArtifactAutoCast[2]; // 21680 _byte_ f_54B2[2]; // +21682 (выравнивание) _bool32_ isCasted[2]; // +21684 _int32_ countMonsters[2]; // +21692 _Army_* army[2]; // +21700 _BattleStack_ stack[2][21]; // +21708 _bool8_ onNativeTerrain[2]; // +78492 _byte_ f_1329E[2]; // +78494 (выравнивание) _int32_ turnsSinceLastEnchanterCast[2]; // +78496 _int32_ summonedElemental[2]; // +78504 _bool8_ sideRetreated[2]; // +78512 _bool8_ sideSurrendered[2]; // +78514 _int32_ gbThisNetHasControl; // +78516 (netControl_BG_A) _int32_ currentStackSide; // +78520 _int32_ currentStackIndex; // +78524 _int32_ currentActiveSide; // +78528 _int32_ autoCombatOn; // +78532 _BattleStack_* activeStack; // +78536 _int32_ highlighterOn; // +78540 _int32_ lastHexIndex; // +78544 _int32_ lastMoveToIndex; // +78548 _int32_ attackerHexIndex; // +78552 _int32_ lastCommand; // +78556 _int32_ combatCommand; // +78560 _int32_ castleAttackDone; // +78564 _Def_* currentSpellDef; // +78568 _int32_ currentSpellID; // +78572 _int32_ currentSpellDefFrame; // +78576 _int32_ numShootingTowers; // +78580 _int32_ isBattleOver; // +78584 _Dlg_* dlg; // +78588 _int32_ bCombatShowIt; // +78592 _dword_* iconWidgetWL[25]; // +78596 (iconWidget = _DlgStaticDef_?) _dword_* textWidgetWL[25]; // +78696 (textWidget = _DlgStaticText_?) _int32_ attackCursorEnumType[12]; // +78796 _int32_ attackHex[12]; // +78844 _int32_ lastAttackCursorEnumType; // +78892 _int32_ iTtlCombatDirections; // +78896 _int32_ iBackgroundFrame; // +78900 _bool8_ bCreatureIsDead[2][20]; // +78904 _bool8_ bSomeCreaturesVanish; // +78944 _byte_ f_13461[3]; // +78945 (выравнивание) char* backPcxName; // +78948 _BattleHexAdjacent_ adjacentSquares[187]; // +78952 (_BattleHexAdjacent_ adjacentSquares[187]) _int32_ saveBiggestExtent; // +81196 _int32_ limitToExtent; // +81200 _int32_ computeExtentOnly; // +81204 _int32_ extent[4]; // +81208 (RECT = size 16 bytes) _int32_ sideWinner; // +81224 _int32_ necromanty_Count; // +81228 _int32_ necromanty_Type; // +81232 _dword_* NumberWindow; // +81236 _List_<_int32_> Obstacles; // +81240 (_H3Vector_<H3Obstacle>) _bool8_ isTactics; // +81256 _byte_ f_13D69[3]; // +81257 (выравнивание) _int32_ round; // +81260 _int32_ tacticsDifference; // +81264 _bool8_ cheatNoSpellLimit; // +81268 _bool8_ cheatShowHiddenObjects; // +81269 _bool8_ cheatShowBlockedHexes; // +81270 _byte_ f_13D77; // +81271 (выравнивание) _dword_* Towers[3]; // +81272 ( struct TownTowerLoaded (size 0x24h) _bool8_ waitPhase; // +81380 _byte_ f_13DE5[3]; // +81381 (выравнивание) _int32_ defenderHeroOriginalPSkill[4]; // +81384 (герой защитник: сохранить атаку до битвы) char* wallImagesNames[90]; // +81400 _int32_ wallLevel[18]; // +81760 _int32_ wallFrame[18]; // +81832 _int32_ mapPoint; // +81904 (пакованные координаты битвы) _Pcx8_* combatCellGrid; // +81908 _Pcx8_* combatCellShaded; // +81912 _int32_ obstacleAnimationFrame; // +81916 _bool8_ redrawCreatureFrame[40];// +81920 _bool8_ redrawHeroFrame[2]; // +81960 _bool8_ redrawFlagFrame[2]; // +81962 _bool8_ redrawTowersFrame[3]; // +81964 _bool8_ askRunBattle; // +81967 _bool8_ anyActionTaken; // +81968 _byte_ creaturePath[187]; // +81969
// normal //inline _Def_* LoadSpellAnimation(int spell_anim_ix) inline int GetHexIxAtXY(int x, int y) {return CALL_2(int, __stdcall, 0x464380, x - dlg->x, y - dlg->y);} inline void CastSpell(int spell_id, int hex_ix, int cast_type_012, int hex2_ix /*для телепорта и жертвы*/, int skill_level, int spell_power) {CALL_7(void, __thiscall, 0x5A0140, this, spell_id, hex_ix, cast_type_012, hex2_ix, skill_level, spell_power);}
// может ли впринципе сторона колдовать любое заклинание inline _bool8_ CanUseAnySpell(int side, _byte_ isHeroCaster) { return CALL_3(_bool8_, __thiscall, 0x41FA10, this, side, isHeroCaster); }
// даём игроку управление для поиска цели уже выбранного заклинания inline void UserChooseSpellTarget(int spell, int position) { return CALL_4(void, __fastcall, 0x59EF60, this, position, spell, 0); }
// скрытая ли битва: 0=видимая, 1=скрытая inline _bool8_ IsHiddenBattle() { return CALL_1(_bool8_, __thiscall, 0x46A080, this); } // Проверка необходимости отрисовки битвы. // При необходимости отрисовки возвращает FALSE, иначе TRUE. inline _bool8_ ShouldNotRenderBattle() { return CALL_1(_bool8_, __thiscall, 0x46A080, this); }
// проиграть анимацию заклинания на активном стеке inline _byte_ StackActive_PlaySpellAnimation(_int_ spell_anim_id, _int_ play_damage_to_stack = 0) { return CALL_3(_byte_, __thiscall, 0x468570, this, spell_anim_id, play_damage_to_stack); }
// поставить тень курсора на гекс inline _int32_ SetCursorShadowOnGex(_int32_ GexID) { return CALL_1(_int32_, __fastcall, 0x59FA10, GexID); }
// получить тип курсора в бою inline _int32_ GetCursorFrame(_int32_ GexID) { return CALL_2(_int32_, __thiscall, 0x475DC0, this, GexID); }
// добавить хинт действия в битве (в лог битвы) НЕ сохранится в логе // в зависимости от типа действия (считывается из кадра курсора мыши) inline void AddHintMessage_ByCursorFrame(_int32_ cursor_frame) { CALL_2(void, __thiscall, 0x4923C0, this, cursor_frame); }
// добавить статус действия в битве (в лог битвы) сохранится в логе inline void AddStatusMessage(const char* statusbar_text) { return CALL_4(void, __thiscall, 0x4729D0, this->dlg, statusbar_text, 1, 0); }
// добавить хинт действия в битве (в лог битвы) НЕ сохранится в логе inline void AddHintMessage(const char* statusbar_text) { return CALL_4(void, __thiscall, 0x4729D0, this->dlg, statusbar_text, 0, 1); }
// получить в текст урона, который можно записать в лог битвы inline _HStr_* GetHintMessage_AttackDamage(_HStr_* H3Str, _BattleStack_* atacker, _BattleStack_* target, _bool8_ isShoot, _int32_ stepsToTarget) { return CALL_5(_HStr_*, __fastcall, 0x492F50, H3Str, atacker, target, isShoot, stepsToTarget); }
// Сделать стек активным inline void SetActiveStack(_int_ side, _int_ index_on_side) { return CALL_3(void, __thiscall, 0x464F10, this, side, index_on_side); }
// Проиграть магическую анимацию на определенном гексе поля боя inline _byte_ PlayMagicAnimationOnGEX(_int_ anim_id, _int_ gex_id) { return CALL_5(_byte_, __thiscall, 0x496590, this, anim_id, gex_id, 100, 1); } // Сброс полей необходимости перерисовки. inline void ClearRedrawFields() { return CALL_1(void, __thiscall, 0x493290, this); } // Указание необходимости перерисовки при следующей отрисовке для стека - стрелковой башни. inline void SetArrowTowerToRedraw(_BattleStack_* Stack) { return CALL_2(void, __thiscall, 0x46A040, this, Stack); }
// получение прямого расстояния между двумя гексами (без учёта препятствий) inline _int_ GetDistance(_int_ gex_start, _int_ gex_finish) { return CALL_2(_int_, __fastcall, 0x469250, gex_start, gex_finish); } // Определение границ перерисовки для кадра def`а. inline void SetSpecRedrawBorders(_Def_* Def, _int_ DefGroupNum, _int_ FrameNum, _int_ X_Pos, _int_ Y_Pos, _RedrawBorders_* out_Borders, _bool_ Reflected, _bool_ NeedAddToGlobalBorders) { CALL_9(void, __thiscall, 0x495AD0, this, Def, DefGroupNum, FrameNum, X_Pos, Y_Pos, out_Borders, Reflected, NeedAddToGlobalBorders); } // Вычисление границ необходимости обновления экрана на основе полей необходимости перерисовки боевых элементов. inline void SetRedrawBorders() { CALL_1(void, __thiscall, 0x495770, this); } // Отрисовка поля боя. // Flip - необходимость обновления экрана. // SetBattleRedraws - необходимость настройки границ обновления экрана. // UseBattleRedraws - необходимость использования границ обновления экрана (при SetBattleRedraws = TRUE игнорируется, считаясь TRUE). // WaitingTime - время, на ожидание которого надо настроить следующую отрисовку (игнорируется при Wait = FALSE). // RedrawBackground - необходимость перерисовки заднего плана (и стёрки старого изображения). // Wait - необходимость ожидания. В случае FALSE время ожидания для следующей отрисовки не меняется. inline void RedrawBattlefield(_bool8_ Flip, _bool8_ SetBattleRedraws, _bool8_ UseBattleRedraws, _int_ WaitingTime, _bool8_ RedrawBackground, _bool8_ Wait) { return CALL_7(void, __thiscall, 0x493FC0, this, Flip, SetBattleRedraws, UseBattleRedraws, WaitingTime, RedrawBackground, Wait); } inline _int32_ RedrawGrid() { return CALL_3(_int32_, __thiscall, 0x4934B0, o_BattleMgr, 0, 1); }
inline void Redraw() { return RedrawBattlefield(1, 0, 0, 0, 1, 0); }
// Обновление всего поля боя. inline void FlipBattlefield() { CALL_1(void, __fastcall, 0x493300, this); }
inline void Highlight_Hex(int gex_id = -1, signed int item = -1) { CALL_3(void, __thiscall, 0x493F10, this, gex_id, item); } // Инициализация переменных, управляющих временем случайных анимаций. inline void InitRandAnimsTimes() { CALL_1(void, __thiscall, 0x479860, this); } // Проигрывание одного кадра анимации ожидания поля боя. // Это анимация флагов героев, анимация самих героев, случайная анимация существ, мигающая рамка вокруг стеков. inline void PlayWaitAnim() { CALL_1(void, __thiscall, 0x495C50, this); } // Проигрывание одного кадра анимации ожидания поля боя только в случае наступления времени. inline void PlayWaitAnimOnce() { CALL_1(void, __thiscall, 0x473970, this); } // Нанесение урона элементу замка по его номеру. inline void DamageCastleElement(_int_ CastleElementNum, _int_ Damage) { CALL_3(void, __thiscall, 0x465570, this, CastleElementNum, Damage); }
inline _bool8_ Get_StackShoot_ObstacklePenalty(_BattleStack_* stack, _int32_ stackHexID, _int32_ gexTargetID) { return CALL_4(_bool8_, __thiscall, 0x4670F0, this, stack, stackHexID, gexTargetID); } inline _bool8_ Get_StackShoot_DistancePenalty(_BattleStack_* stack, _BattleStack_* target) { return CALL_3(_bool8_, __thiscall, 0x4671E0, this, stack, target); } // Удаление стека с гекса, на котором он стоит. inline void RemoveStackFromGexes(_BattleStack_* stack) { CALL_2(void, __thiscall, 0x468310, this, stack); } // Постановка стека на гекс. inline void PutStackToGex(_BattleStack_* Stack, _int_ GexNum) { CALL_3(void, __thiscall, 0x4683A0, this, Stack, GexNum); } // Удаление препятствия. inline void RemoveObstacle(_int_ ObstacleNum) { CALL_2(void, __thiscall, 0x466710, this, ObstacleNum); }
// проверка препятствий на гексе (0-пуст, 1-занят) inline _byte_ IsGexNotObstacle(_int_ gexID) { // проверяем, правильно ли передали в функцию номер гекса if (gexID <= 0 || gexID > 187) return 1; // не правильно, значит гекс занят
return CALL_2(_byte_, __thiscall, 0x4695F0, this, gexID); } }
PHP Code:
NOALIGN struct _BattleStack_ : _Struct_ // размер 0x548 = 1352 байта { _byte_ bShowAttackFrames; // +0 _byte_ bShowRangeFrames; // +1 _byte_ iShowAttackFrameType; // +2 _byte_ iNextFrameType; // +3 _byte_ iRemainingFrames; // +4 _byte_ field_05[3]; // +5 выравнивание стуктуры
_int32_ iDrawPriority; // +8 _byte_ bShowTroopCount; // +12 0x0C _byte_ field_0D[3]; // +13 0x0D выравнивание стуктуры
_dword_ targetStackSide; // +16 0x10 _dword_ targetStackIndex; // +20 0x14 _dword_ targetAttackLimit; // +24 0x18
_int32_ targetGexID; // 28 +0x1C позициякуда бежать/стрелять
_byte_ isFireshield; // +32 0x20 огненный щит _byte_ field_21[3]; // +33 0x21 выравнивание стуктуры
_int32_ clone_owner_stack_ix; //+36 _int32_ clone_index; // +40 0x28 (id стэка клона) _dword_ clone_rounds_left_to_vanish; // +44 0x2C (число раундов до исчезновения)
_byte_ isMoving; // +48 0x30 _byte_ letsPretendImNotHere; // +49 0x31 _byte_ field_32[2]; // +50 0x30 выравнивание стуктуры
_int32_ creature_id; // +52 0x34 (тип монстра) _int32_ hex_ix; // +56 0x38 (позиция на поле боя) _int32_ def_group_ix; // +60 0x3C _int32_ def_frame_ix; // +64 0x40
_dword_ orientation; // +68 0x44 направление монстра (1-как атакующий, 0-как защитник) _dword_ walkDirection; // +72 0x48 ?
_int32_ count_current; // +76 0x4C (число монстров) _int32_ count_before_attack; // +80 0x50 (число монстров до удара по ним в тек. атаку) _dword_ count_battle_resurrected; // +84 0x54 _int32_ lost_hp; // +88 0x58 потери здоровья последнего монстра _int32_ army_slot_ix; // +92 0x5C номер слота of _Army_ (0...6), -1 - будет удален после битвы _int32_ count_at_start; // +96 0x60 число монстров в начале битвы _dword_ base_speed; // +100 0x64 базовая скорость с бонусами земли, спецов и т.д. По ней видимо вычисляются ускорение и замедление _dword_ anim_value; // +104 0x68 = cranim.f[15] при инициализации _int32_ full_hp; // +108 0x6C полное здоровье (исп. как база для лечения) _bool32_ isLucky; // +112 0x70 в этом раунде была удача
////////////////////////////////////////////////////////////////////////////////// _CreatureInfo_ creature; ////////////////////////////////////////////////////////////////////////////////// //_int_ town; //+116 0x74 //_int_ level; //+120 0x78 //_char_* sound_name; //+124 0x7C //_char_* def_name; //+128 0x80 //_int_ flags; //+132 0x84 //_char_* name_single; //+136 0x88 //_char_* name_plural; //+140 0x8C //_char_* specification_description; //+144 0x90 //_int_ cost_wood; //+148 0x94 //_int_ cost_mercury; //+152 0x98 //_int_ cost_ore; //+156 0x9C //_int_ cost_sulfur; //+160 0xA0 //_int_ cost_crystal; //+164 0xA4 //_int_ cost_jems; //+168 0xA8 //_int_ cost_gold; //+172 0xAC //_int_ fight_value; //+176 0xB0 //_int_ AI_value; //+180 0xB4 //_int_ growth; //+184 0xB8 //_int_ horde_growth; //+188 0xBC //_int_ hit_points; //+192 0xC0 //_int_ speed; //+196 0xC4 //_int_ attack; //+200 0xC8 //_int_ defence; //+204 0xCC //_int_ damage_min; //+208 0xD0 //_int_ damage_max; //+212 0xD4 //_int_ shots; //+216 0xD8 //_int_ spells_count; //+220 0xDC //_int_ advmap_low; //+224 0xE0 //_int_ advmap_high; //+228 0xE4 ///////////////////////////////////////////////////////////////////////////////
_byte_ show_fire_shield; // +232 0xE8 (например у Ифритов он не отображается) _bool8_ isSomeKilled; // +233 0xE9 =1, если умирал хоть один _bool8_ isAllKilled; // +234 0xEA =1, если был убит весь стэк
_byte_ field_EB; // +235 0xEB выравнивание структуры
_int32_ spellAfterAttack; // +236 0xEC номер заклинания существа в тек раунде 0x50 Acid breath _int32_ hitByCreature; // +240 0xF0 _byte_=1 перед атакой на него 441434 _int32_ side; // +244 0xF4 0 - attacker, 1 - defender _dword_ index_on_side; // +248 F8 dd = номер стэка у стороны на поле боя
_dword_ iLastFidgetTime; // +252 FC dd = ? что-то с магией _dword_ ySpecialMod; // +256 100 dd 43DEA4 _dword_ xSpecialMod; // +260 104 dd 43DEAD _dword_ bPowSequenceComplete; // +264 108 dd _dword_ yModify; // +268 10C dd _CreatureAnim_ cr_anim; // +272 0x110 _Def_* def; // +356 0x164 def монстра, загрузка: 43DA8E _Def_* def_shot; // +360 0x168 def выстрела, загрузка: 43DA8E _dword_ image_height; // +364 0x16С _Wav_* wav_move; // +368 0x170 звук перемещения (move), загрузка: 43DA8E _Wav_* wav_attack; // +372 0x174 звук атаки (attk/wnce/shot), загрузка: 43DA8E _Wav_* wav_wnce; // +376 0x178 звук 'колдует' (wnce), загрузка: 43DA8E _Wav_* wav_shot; // +380 0x17C звук выстрела (shot), загрузка: 43DA8E _Wav_* wav_kill; // +384 0x180 звук смерти (kill), загрузка: 43DA8E _Wav_* wav_defend; // +388 0x184 звук обороны (wnce/dfnd), загрузка: 43DA8E _Wav_* wav_ext1; // +392 0x188 звук дополнительный 1 (ext1), загрузка: 43DA8E _Wav_* wav_ext2; // +396 0x18С звук дополнительный 2 (ext2), загрузка: 43DA8E _dword_ turnsToNextMove; // +400 0x190 _int32_ active_spells_count; // +404 0x194 dd = количество уже наложенных заклинаний _int32_ active_spell_duration[81]; // +408 0x198 есть заклинание (длительность) или нет _int32_ active_spells_power[81]; // +732 0x2DC (сила действия заклинания) _byte_ SpellInfluenceQueue[48]; // +1056 0x420 std::deque
_int32_ PaletteEffect; // +1104 0x450 _int32_ retaliations; // +1108 0x454 // 441B17 (кол-во ответов на атаку 0= не отв. на атаку)// настройка для грифонов 46D6A0 _int32_ bless_value; // +1112 0x458 Bless добавка к Max. Damage _int32_ curse_value; // +1116 0x45C Curse убавка к Min. Damage _int32_ antimagic_value; // +1120 0x460 _int32_ bloodlast_value; // +1124 0x464 Bloodlast добавка к Атаке с бонусами _int32_ precision_value; // +1128 0x468 Precision добавка к Атаке с бонусами _int32_ weaknessPenalty; // +1132 0x46C _int32_ stoneSkinBonus; // +1136 0x470 _int32_ disruptiverayPenalty; // +1140 0x474 _int32_ prayerBonus; // +1144 0x478 _int32_ mirthBonus; // +1148 0x47C _int32_ sorrowPenalty; // +1152 0x480 _int32_ fortuneBonus; // +1156 0x484 _int32_ misfortunePenalty; // +1160 0x488 _int32_ slayerLevel; // +1164 0x48C _int32_ steps_to_target; // +1168 0x490 dd (шаги до цели) _int32_ counerstrike_retaliations; // +1172 0x494 dd кол. доп. ответов на атаку, добавленных Counerstrike заклом _int32_ frenzyAdjust; // +1176 0x498 _int32_ blindFactor; // +1180 0x49C _int32_ fire_shield_strength; // +1184 0x4A0 _int32_ poison_penalty; // +1188 0x4A4
_int32_ protectionFromAirFactor; // +1192 0x4A8 _int32_ protectionFromFireFactor; // +1196 0x4AC _int32_ protectionFromWaterFactor; // +1200 0x4B0 _int32_ protectionFromEarthFactor; // +1204 0x4B4
_int32_ shieldDamageFactor; // +1208 0x4B8 _int32_ airShieldDamageFactor; // +1212 0x4BC _bool8_ residualBlindness; // +1216 0x4C0 db Blinded - снизить защиту (сбросить после?) при атаке на него (уст. перед ударом) _bool8_ residualParalyze; // +1217 0x4C1 db Paralized - снизить защиту (сбросить после?) при атаке на него (уст. перед ударом) _bool8_ field4C2[2]; // +1218 0x4C2 выравнивание структур
_int32_ forgetfulness_level; // +1220 0x4C4 dd Forgetfulness - уровень (>2 - не может стрелять) _int32_ slowPenalty; // +1224 0x4C8 _int32_ hasteBonus; // +1228 0x4CС
_int32_ diseaseDefensePenalty; // +1232 0x4D0 _int32_ diseaseAttackPenalty; // +1236 0x4D4 _byte_ isNativeTerrain; // +1240 0x4D8 _byte_ field_4C9[3]; // +1241 0x4D9 выравнивание структуры _int32_ defend_bonus; // +1244 0x4DC dd = величина бонуса при выборе защиты _int32_ faerie_dragon_spell; // +1248 0x4E0 dd заклинание для сказ дракона
_int32_ magicMirrorChance; // +1252 0x4E4 _int32_ morale; // +1256 0x4E8 _int32_ luck; // +1260 0x4EC
_byte_ resetOnThisRound; // +1264 0x4F0 _byte_ isAreaEffectTarget; // +1265 0x4F1
_byte_ field_4F2[2]; // +1266 0x4F2 выравнивание структуры
_List_<_int32_> binder_clients; // +1268 0x4F4 (bound_armies std::vector) _List_<_int32_> binder_sources; // +1284 0x504 (binder std::vector) _List_<_int32_> aura_clients; // +1300 0x514 (aura_clients std::vector) _List_<_int32_> aura_sources; // +1316 0x524 (aura_clients std::vector)
_int32_ AI_expected_damage; // +1332 0x534 _int32_ AI_target; // +1336 0x538 _int32_ AI_target_value; // +1340 0x53C _int32_ AI_target_distance; // +1344 0x540 _int32_ AI_possible_targets; // +1348 0x544
// normal inline void Construct(int creature_id, int count, _Hero_* hero_owner, int side, int index_on_side/*0 - 21*/, int position_hex_ix, int army_slot_ix) {CALL_8(void, __thiscall, 0x43D5D0, this, creature_id, count, hero_owner, side, index_on_side, position_hex_ix, army_slot_ix);}
inline _BattleStack_* Create() {return CALL_1(_BattleStack_*, __thiscall, 0x43CF70, this);} // need (_BattleStack_*)o_New(sizeof(_BattleStack_)) inline void InitDefsAndWavs() {CALL_1(void, __thiscall, 0x43D710, this);} inline _int32_ InitSpells() {return CALL_1(_int32_, __thiscall, 0x43D2E0, this);} inline _int32_ Delete() {return CALL_1(_int32_, __thiscall, 0x43D120, this);}
inline _int32_ GetFullHealth(_bool_ isAI) {return CALL_2(_int32_, __thiscall, 0x442DA0, this, isAI);} inline _int32_ GetSide() {return CALL_1(_int32_, __thiscall, 0x43FE60, this);}
// получение базового урона монстром inline _int32_ Calc_Damage_Base(_bool_ isTeoretic = TRUE) { return CALL_2(_int32_, __thiscall, 0x442E80, this, isTeoretic); } // Подсчёт добавок к наносимому урону (возвращается новый урон). // Enemy - указатель на атакуемый стек. // BaseDamage - начальный урон. // IsShot - является ли атака выстрелом (TRUE - является). // Virtual - является ли подсчёт производимым ИИ (TRUE - является). // WayLength - пройденный путь до цели (для расчёта кавалерийского бонуса). // out_FireshieldDamage - указатель на переменную, в которую в результате работы функции запишется урон от огненного щита (0 - не подсчитывать). inline _int32_ Calc_Damage_Bonuses(_BattleStack_* enemy, _int32_ BaseDamage, _bool8_ IsShot, _bool8_ Virtual, _int32_ WayLength, _int32_* out_FireshieldDamage) { return CALL_7(_int32_, __thiscall, 0x443C60, this, enemy, BaseDamage, IsShot, Virtual, WayLength, out_FireshieldDamage); }
// Проиграть анимацию заклинания на стеке inline _int_ PlayMagicAnimation(_int_ spell_anim_id, _byte_ is_show_damage = 0) { return CALL_5(_int_, __thiscall, 0x4963C0, o_BattleMgr, spell_anim_id, this, 100, is_show_damage); }
// проиграть анимацию заклинания на активном стеке (почему их 2 функции?) inline _byte_ PlayMagicAnimation2(_int_ spell_anim_id, _int_ is_show_damage = 0) { return CALL_3(_byte_, __thiscall, 0x468570, o_BattleMgr, spell_anim_id, is_show_damage); }
// Проиграть анимацию самого стека inline _byte_ PlayStackAnimation(_int_ anim_id, _int_ is_restore_state) { if (is_restore_state) // если необходимо восстановить исходную стойку { CALL_4(_byte_, __thiscall, 0x446660, this, anim_id, -1, 0); return CALL_4(_byte_, __thiscall, 0x446660, this, 2, 1, 0); } else return CALL_4(_byte_, __thiscall, 0x446660, this, anim_id, -1, 0); }
// Сделать этот стек активным inline void SetActiveThisStack() { return CALL_3(void, __thiscall, 0x464F10, o_BattleMgr, this->side, this->index_on_side); }
// переместить стек (если не хватает дальности хода, стек не двинется) inline _byte_ Move(_int_ gex_id) { return CALL_3(_byte_, __thiscall, 0x445A30, this, gex_id, 0); }
// поворот стека в противоположную сторону inline _byte_ Rotate() { return CALL_2(_byte_, __thiscall, 0x445A30, this, 1); }
// Атаковать стеком (врукопашную) inline _byte_ Attack_Melee(_BattleStack_* enemy) { return CALL_3(_byte_, __thiscall, 0x441330, this, enemy, 2); }
// Атаковать стеком (стрелять) inline void Attack_Shoot(_BattleStack_* enemy) { return CALL_2(void, __thiscall, 0x43F620, this, enemy); }
// Отрисовка выстрела стека по противнику и полёта снаряда. inline void Draw_Shot(_BattleStack_* enemy) { CALL_2(void, __thiscall, 0x43EFE0, this, enemy); }
// может ли стрелять с проверкой на врага рядом _bool8_ CanShoot(_BattleStack_* aim = NULL) { return CALL_2(_bool_, __thiscall, 0x442610, this, aim); }
// впринципе умеет ли стрелять (без проверки на врага рядом) _bool8_ CanShoot2(_BattleStack_* aim = NULL) { if (this->creature_id == CID_ARROW_TOWER) return TRUE; if ( (this->creature.flags & BCF_CAN_SHOOT) && this->creature.shots > 0) return TRUE;
return FALSE; } // Получение второго гекса, занимаемого стеком (если стек 1-клеточный, первого). inline _int32_ GetSecondGexID() { return CALL_1(_int32_, __thiscall, 0x4463C0, this); } // Уничтожение стека. // dead_itself - умер ли стек сам собой (например, как клон при гибели хозяина или окончании длительности заклинания). inline void Die(_bool8_ dead_itself) { CALL_2(void, __thiscall, 0x443E40, this, dead_itself); }
// получение скорости стека inline _int_ GetSpeed() { return CALL_1(_int_, __thiscall, 0x4489F0, this); }
// может ли дойти стек до цели inline _int_ CanReachToTarget(int gex_target, int a3 = 0, int a4 = 0) { return CALL_4(_int_, __thiscall, 0x446960, this, gex_target, a3, a4); }
// получить иммунитет существа // caster_type: 0 - герой 1 - монстр, 2 - арт inline double GetResistMagic(int spell_id, int side, char a5, char a6, int caster_type) { return CALL_7(double, __thiscall, 0x5A83A0, o_BattleMgr, spell_id, side, this, a5, a6, caster_type); }
// получить ослабление силы магии (големы) inline int GetResistGolem(int spell_id, int damage) { return CALL_3(int, __fastcall, 0x44B180, damage, spell_id, this->creature_id); }
// получить получить ослабление силы магии (защита от воды и т.п.) inline int GetResistSpellProtection(int spell_id, signed int damage) { return CALL_3(int, __stdcall, 0x5A7EC0, damage, spell_id, this); }
// может ли колдовать как Сказочный Дракон inline _bool8_ CanCastSpellAkaFaerieDragon() { if (this->faerie_dragon_spell && this->creature.spells_count) { return TRUE; } return FALSE; }
// может ли монстр колдовать на позицию inline _bool8_ CanCastToGex(int targetPos) { return CALL_2(_bool8_, __thiscall, 0x4473E0, this, targetPos); }
// может ли монст колдовать на поле боя (расширенная функция указанной выше) _bool8_ CanCastToBattleField() { _bool8_ result = FALSE; for(int i=0; i<=187; i++) { if(this->CanCastToGex(i)) { result = TRUE; break; } } return result; }
// можно ли кастовать на монстра // 5A3F90 bool __thiscall CombatMan_CanUseSpell(_BattleMgr_ *this, int spell, int side, _BattleStack_ *targetMon, int a5, int a6) inline bool CanUseSpell(int spell_id, int side, char a5, int caster_type) { return CALL_6(bool, __thiscall, 0x5A3F90, o_BattleMgr, spell_id, side, this, a5, caster_type); }
// получить кол-во воскрешаемых существ (Архангелы или Пит-Лорды) inline int Get_Resurrect_Count(_BattleStack_* stack_target) { return CALL_2(int, __thiscall, 0x447050, this, stack_target); } // Получение номера стрелковой башни стека (-1 - стек не является стрелковой башней). inline _int32_ Get_ArrowTowerNum() { // Выбираем номер стрелковой башни в зависимости от её позиции (стандартный способ игры). switch (this->hex_ix) { case 254: return 0; case 251: return 1; case 255: return 2; default: return -1; } }
// WOG ФУНКЦИИ #define WOG_IS_HARPY *(_byte_*)0x75E05B #define WOG_IS_HARPY_HAG *(_byte_*)0x75E060 #define WOG_IS_DARKNESS_DRAGON *(_dword_*)0x75E064 _bool8_ WOG_isHarpy() { if( this->creature_id == WOG_IS_HARPY || this->creature_id == WOG_IS_HARPY_HAG || this->creature_id == WOG_IS_DARKNESS_DRAGON || CALL_1(int, __cdecl , 0x71E433, this) ) { return TRUE; } return FALSE; } };
PHP Code:
NOALIGN struct _AdvMgr_: _Struct_ // size: 952 bytes = 0x3B8 { _Manager_ mgr; // 0...56 _ptr_ pNetMsgHandler; // +56 0x38 _byte_ DebugShowFPS; // +60 0x3C _byte_ DebugViewAll; // +61 0x3D _byte_ f_3E[2]; // +62..63 выравнивание _int_ advCommand; // +64 0x40 _ptr_ advWindow; // +68 0x44 _ptr_ pRouteArray; // +72 0x48 _int_ bShowRoute; // +76 0x4C _int_ seedingValid; // +80 0x50 _int_ fullySeeded; // +84 0x54 _int_ lastTerrain; // +88 0x58 _GameMap_* map; // +92 0x5C _Def_* groundTileset[10]; // +96 0x60 _Def_* riverTileset[5]; // +136 0x88 _Def_* roadTileset[4]; // +156 0x9C _Def_* borderTileset; // +172 0xAC _Def_* arrowTileset; // +176 0xB0 _Def_* gemIcons[4]; // +180 0xB4 _Def_* starTileset; // +196 0xC4 _Def_* radarIcons; // +200 0xC8 _Def_* cloudIcons; // +204 0xCC _H3Vector_ CachedGraphics; // +208 0xD0 _Def_* monAttackSprites; // +224 0xE0 type_point mapOrigin; // +228 0xE4 type_point lastMapHover; // +232 0xE8 _int_ lastHoverX; // +236 0xEC _int_ lastHoverY; // +240 0xF0 _int_ scrollX; // +244 0xF4 _int_ scrollY; // +248 0xF8 _int_ animFrame; // +252 0xFC _int_ animCtr; // +256 0x100 _byte_ animCtrPaused; // +260 0x104 _byte_ f_105[3]; // +261...263 выравнивание _int_ flagFrame; // +264 0x108 _Def_* cursorIcons[18]; // +268 0x10C _Def_* boatIcons[3]; // +340 0x154 _Def_* boatFrothIcons[3]; // +352 0x160 _Def_* flagIcons[8]; // +364 0x16C _Def_* boatFlagIcons[24]; // +396 0x18C _byte_ heroVisible; // +492 0x1EC _byte_ f_1ED[3]; // +493...495 выравнивание _int_ heroType; // +496 0x1F0 _int_ heroDirection; // +500 0x1F4 _int_ heroBaseFrame; // +504 0x1F8 _int_ heroSequence; // +508 0x1FC _int_ heroFrameCount; // +512 0x200 _int_ heroTurning; // +516 0x204 _int_ heroDrawn; // +520 0x208 _byte_ bCurHeroMobile; // +524 0x20C _byte_ f_20D[3]; // +525...527 выравнивание _int_ iShowMode; // +528 0x210 _int_ bForceCompleteDraw; // +532 0x214 _int_ monAttackObjIndex; // +536 0x218 _int_ monAttackSpriteIndex; // +540 0x21C _int_ monAttackFlip; // +544 0x220 _int_ touchedSounds; // +548 0x224 _SoundNode_ soundArray[4]; // +552 0x228 _Wav_* loopedSample[70]; // +584 0x248 _Wav_* heroSamples[11]; // +864 0x360 _int_ bHeroLogoShowing; // +908 0x38C _byte_ bHeroMoving; // +912 0x390 _byte_ f_391[3]; // +913...915 выравнивание _int_ CurrentBottomView; // +916 0x394 (enum EBottomViewType) _int_ BottomViewOverride; // +920 0x398 (enum EBottomViewType) _int_ BottomViewOverrideEndTime; // +924 0x39C _int_ BottomViewResource; // +928 0x3A0 _int_ BottomViewResourceQty;// +932 0x3A4 _H3Str_ BottomViewText; // +936 0x3A8 (std::string) // end: +952 0x3B8 };
_SoundNode_ // Size = 8 { _int_ soundId; // enum e_looping_sound_id _int_ priority; }
enum AdvManager::EBottomViewType { BVTYPE_NONE = 0, BVTYPE_NEW_TURN = 1, BVTYPE_KINGDOM = 2, BVTYPE_HERO = 3, BVTYPE_TOWN = 4, BVTYPE_ENEMY_TURN = 5, BVTYPE_RESOURCE_MESSAGE = 6, BVTYPE_MESSAGE = 7, BVTYPE_HOLD = 8 }
game bug fixes extended.dll || My Plugins || My GitHub
|