Объявления
Поздравляем
Roman2211


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

База данных IDA от void17

Герои Меча и Магии 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: База данных IDA от void17

Сообщение AlexSpl » 29 ноя 2021, 16:07

OK. Но в RoE уже были Dread Knights. Просто в SoD подсчёт бонуса к урону для всех существ, кроме Dread Knights и Ballista, завернули в отдельную функцию. Такой вот "обратный инлайн".

Более того, в SoD расчёт бонуса к урону для Dread Knights и Ballista идёт после расчёта бонусов is_natural_enemy()! Поэтому это не враппер, а сама функция. Та функция, которая есть сейчас, - это подфункция. Я добавил префикс "SoD_".
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 29 ноя 2021, 17:39

Функция 0x443C60, которая сейчас с сигнатурой public: long army::DamageEnemy(army *,int *,int *,bool), на самом деле имеет сигнатуру public: long __cdecl army::adjust_damage(class army *, long, bool, bool, long, long *)const. Теперь всё стало на свои места, а public: long army::DamageEnemy(army *,int *,int *,bool) нужно искать дальше.

Вот такие параметры у неё:

Код: Выделить всё
; int __thiscall army::adjust_damage(const army *this, army *enemy, int damage, bool canShoot, bool isQuickCombat, int hexDistance, int *refFireShieldDmg)
.text:00443C60     public: long army::adjust_damage(army *,long,bool,bool,long,long *)const proc near


* * *
Два интересных поля army (AI):

+0x540 - указатель на отряд-цель;
+0x548 - расстояние до отряда-цели в раундах.

* * *
Heroes3f.zip
(14.05 МБ) Скачиваний: 145

Зелёным отмечены полностью декомпилированные функции ("Mark as decompiled").
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 29 ноя 2021, 23:52

Судя по этому коду:

Код: Выделить всё
if ( (flags_2 & (CF_SACRIFICED|CF_SUMMONED)) != 0 )
{
  gpCombatManager->f_13300[20 * this_1->side + 0x138 + this_1->sideIndex] = 1;
  gpCombatManager->f_13300[0x160] = 1;
}

из void __thiscall army::ProcessDeath(army *this, int a2), в булевом массиве менеджера боя по смещению 0x13300 + 0x138 = 0x13438 отмечаются принесённые в жертву и погибшие вызванные отряды. Замыкает массив ещё один флаг 0x13460, который устанавливается в true, когда отряд приносится в жертву или когда погибает призванный отряд.

Итого:

Код: Выделить всё
if ( (flags_1 & (CF_SACRIFICED|CF_SUMMONED)) != 0 )
{
  gpCombatManager->sacrificedOrDestroyedSummoned[i->side][i->sideIndex] = 1;
  gpCombatManager->fSacrificedOrDestroyedSummoned = 1;
}

Код: Выделить всё
char f_13300[312];
bool sacrificedOrDestroyedSummoned[2][20];
bool fSacrificedOrDestroyedSummoned;
bool align_13461[3];

Мне пришлось переанализировать функцию, чтобы изменился декомпилированный листинг (U + P). Может, можно обновить без этого? А то слетают названия локальных переменных.

И ещё, судя по глобальному циклу в этом методе, флаг CF_IMMOBILE используется для уничтоженных отрядов. Тогда нужно переименовывать. Есть контрпримеры?
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 30 ноя 2021, 00:50

Я поражаюсь вашей продуктивности. В чем секрет энергии кота Бориса?
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 01:33

Я ещё и плагин параллельно пишу :smile1: Уже нашёл один пример использования поля +0x2DC в коде AI, буду пилить заплатку.
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 30 ноя 2021, 01:42

Нужно полностью разобрать combatManager
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 01:44

Там уже мало осталось, а кое-какие старые поля неправильные, но я ещё уточняю:

Код: Выделить всё
#pragma pack(push, 1)
struct combatManager
{
  void *VMT;
  baseManager *NextManager;
  baseManager *PrevManager;
  int field_C;
  int orderIndex;
  char managerName[32];
  int attached;
  int (__thiscall ***func_ptr_0)(_DWORD, int);
  enum ECombatAction action;
  int actionParameter;
  int actionTargetHex;
  int actionParameter2;
  char accessableSquares[187];
  char accessableSquares2[187];
  char field_1C2;
  char field_1C3;
  hexcell squares[187];
  int landType;
  int field_5398;
  int cycleType;
  int absoluteObstacleID;
  int siegeKindStrange;
  bool hasMoat;
  bool hasDoubleMoat;
  char field_53AA;
  char field_53AB;
  void (__thiscall ***func_ptr_1)(_DWORD, int);
  Bitmap16Bit *drawBuffer;
  void (__thiscall ***func_ptr_2)(_DWORD, int);
  int doNotDrawShade;
  NewmapCell *mapItem;
  int specialGround;
  bool inAntiMagicGarrison;
  bool creatureBankBattle;
  bool battleOnWater;
  char field_53C7;
  town *town;
  hero *hero[2];
  int heroSpellPower[2];
  char field_53DC;
  char field_53DD;
  char field_53DE;
  char field_53DF;
  char field_53E0;
  char field_53E1;
  char field_53E2;
  char field_53E3;
  int heroAnimation[2];
  int heroAnimationFrame[2];
  char field_53F4;
  char field_53F5;
  char field_53F6;
  char field_53F7;
  char field_53F8;
  char field_53F9;
  char field_53FA;
  char field_53FB;
  int time_53FC;
  int time_5400;
  CSprite *heroDefLoaded[2];
  CSprite *heroFlagLoaded[2];
  int heroFlagCadre[2];
  RECT heroUpdateRect[2];
  RECT heroFlagUpdateRect[2];
  std::vector eagleEyeVector[2];
  bool massSpellTarget[2][20];
  bool isNotAI[2];
  bool isHuman[2];
  int heroOwner[2];
  bool hasArtifactAutoCast[2];
  bool wieldingAngelicAlliance[2];
  int heroCasted[2];
  int armyNum[2];
  armyGroup *armyGroup[2];
  army army[2][21];
  char f_1329C[4];
  int turnsSinceLastEnchanterCast[2];
  char _f_132A8[16];
  int currentMonSide;
  int currentMonIndex;
  int currentActiveSide;
  int autoCombat;
  army *activeStack;
  char blueHighlight;
  char _f_132CD[3];
  int creature_at_mouse_pos;
  int mouse_coord;
  int attacker_coord;
  int move_type;
  char _f_132E0[20];
  int siegeKind2;
  int finished;
  void *dlg;
  char f_13300[312];
  bool sacrificedOrDestroyedSummoned[2][20];
  bool fSacrificedOrDestroyedSummoned;
  bool align_13461[3];
  LPCSTR backgroundPcxName;
  H3AdjacentSquares adjacentSquares[187];
  char _f_13D2C[12];
  RECT updateRect;
  char _f_13D48[12];
  int cmNumWinPcxLoaded;
  std::vector obstacleInfo;
  bool tacticsPhase;
  char _f_13D69[3];
  int turn;
  int tacticsDifference;
  char _f_13D74[4];
  TownTowerLoaded towers[3];
  int waitPhase;
  int heroDAttack;
  int heroDDefense;
  int heroDSpellPower;
  int HeroDSpellPoints;
  int TownPicturesLoaded[90];
  int fortWallsHP[18];
  int fortWallsIntact[18];
  char f_13FF0[4];
  void *cCellGrdPcx;
  void *cCellShdPcx;
  int globalCadreIndex;
  bool redrawCreatureFrame[2][20];
  bool heroAnim[2];
  bool heroFlagAnim[2];
  bool turretAnim[3];
  char f_14030[189];
};
#pragma pack(pop)

Конец army тоже интересный. Там всего несколько полей осталось разобрать:

Код: Выделить всё
#pragma pack(push, 1)
struct __declspec(align(2)) army
{
  char f_000[52];
  enum ECreatureType type;
  int hex;
  int animation;
  int animationFrame;
  int secondHexOrientation;
  char f_048[4];
  int numberAlive;
  int previousNumber;
  char f_054[4];
  int healthLost;
  int slotIndex;
  int numberAtStart;
  int f_064;
  int f_068;
  int baseHP;
  int luckValue;
  H3CreatureInformation creatureInfo;
  char f_0E8[4];
  enum SpellID spellToApply;
  char f_0F0[4];
  int side;
  int sideIndex;
  unsigned int last_animation_time;
  int yOffset;
  int xOffset;
  char f_108[8];
  H3MonsterAnimation cranim;
  int *def;
  int *shootingDef;
  char f_16C[4];
  unsigned int moveSound;
  unsigned int attackSound;
  unsigned int getHitSound;
  unsigned int shotSound;
  unsigned int deathSound;
  unsigned int defendSound;
  unsigned int extraSound1;
  unsigned int extraSound2;
  int f_190;
  int activeSpellsNumber;
  int activeSpellDuration[81];
  int activeSpellsLevel[81];
  char f_420[52];
  int retaliations;
  int blessDamageBonus;
  int curseDamagePenalty;
  int anti_magic;
  int bloodlust_effect;
  int precision_effect;
  int weakness_effect;
  int stone_skin_effect;
  int unknown13;
  int prayer_effect;
  int mirth_effect;
  int sorrow_effect;
  int fortune_effect;
  int misfortune_effect;
  int slayer_type;
  int unknown14;
  int counterstrike_effect;
  float frenzyMultiplier;
  int blind_effect;
  float fire_shield_effect;
  int unknown16;
  float protection_air_effect;
  float protection_fire_effect;
  float protection_water_effect;
  float protection_earth_effect;
  int effectShield;
  int effectAirShield;
  bool blinded;
  bool paralyzed;
  char _f_4C2[2];
  TSkillMastery forgetfulnessMastery;
  float slow_effect;
  int haste_effect;
  int disease_attack_effect;
  int disease_defense_effect;
  char _f_4D8[8];
  int faerie_dragon_spell;
  int magic_mirror_effect;
  int morale;
  int luck;
  char _f_4F0[4];
  vector dendroidBinder;
  vector dendroidBinds;
  char _f_514[20];
  int hypnotize_528;
  int hypnotize_52C;
  int f_530;
  int health_AI_unk;
  army *targetArmy;
  int f_53C;
  int distanceToTargetArmy;
  int bfTargetArmies;
};
#pragma pack(pop)

Везде, кстати, нужно поменять выравнивание на 4 и выбросить мусорные байты. Вот это - char _f_514[20]; - смахивает на два вектора. А нет, у вектора же размер 0x10, а не 10 :smile14:
Вернуться к началу

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: База данных IDA от void17

Сообщение AlexSpl » 30 ноя 2021, 02:15

Нашёл 0x514 поле army. Очень похоже на ?remove_aura@army@@QAAXXZ sub_448A40, убирает ауру.

Но такая функция уже есть в базе :smile5:

Смотрите на это:

Код: Выделить всё
.text:0005A3C2                 mov.l   #army::remove_aura(void), r0 ; end of block
.text:0005A3C2                                         ; end of block
.text:0005A3C4                 jsr     @r0 ; ?remove_aura@army@@QAAXXZ
.text:0005A3C6                 mov     r8, r4
.text:0005A3C8                 mov.l   #army::remove_binding(void), r0
.text:0005A3CA                 jsr     @r0 ; ?remove_binding@army@@QAAXXZ
.text:0005A3CC                 mov     r8, r4
.text:0005A3CE                 mov.w   #h'274, r0
.text:0005A3D0                 mov.l   @(r0,r8), r3
.text:0005A3D2                 tst     r3, r3
.text:0005A3D4                 bf      loc_5A420
.text:0005A3D6                 mov.l   #Random(int,int), r0
.text:0005A3D8                 mov     #100, r5
.text:0005A3DA                 jsr     @r0 ; ?Random@@YAHHH@Z
.text:0005A3DC                 mov     #1, r4
.text:0005A3DE                 mov     #60, r2
.text:0005A3E0                 cmp/gt  r0, r2
.text:0005A3E2                 bf      loc_5A3FA
.text:0005A3E4                 mov.l   #army::get_owning_side(void), r0
.text:0005A3E6                 jsr     @r0 ; ?get_owning_side@army@@QBAHXZ
.text:0005A3E8                 mov     r8, r4
.text:0005A3EA                 mov     #1, r3
.text:0005A3EC                 mov.l   #combatManager * gpCombatManager, r1
.text:0005A3EE                 mov.w   #21484, r2
.text:0005A3F0                 mov.l   @r1, r1
.text:0005A3F2                 add     r2, r1
.text:0005A3F4                 mov.b   r3, @(r0,r1)
.text:0005A3F6                 bra     loc_5A420       ; end of block
.text:0005A3F8                 nop
.text:0005A3FA ; ---------------------------------------------------------------------------
.text:0005A3FA
.text:0005A3FA loc_5A3FA:                              ; CODE XREF: army::ProcessDeath(int)+42↑j
.text:0005A3FA                 mov.l   #Random(int,int), r0
.text:0005A3FC                 mov     #100, r5
.text:0005A3FE                 jsr     @r0 ; ?Random@@YAHHH@Z
.text:0005A400                 mov     #1, r4
.text:0005A402                 mov     #80, r2
.text:0005A404                 cmp/gt  r0, r2
.text:0005A406                 bf      loc_5A420
.text:0005A408                 mov.l   #army::get_owning_side(void), r0
.text:0005A40A                 jsr     @r0 ; ?get_owning_side@army@@QBAHXZ
.text:0005A40C                 mov     r8, r4
.text:0005A40E                 mov     #1, r3
.text:0005A410                 mov.l   #combatManager * gpCombatManager, r1
.text:0005A412                 sub     r0, r3
.text:0005A414                 mov.l   @r1, r1
.text:0005A416                 mov     r3, r0
.text:0005A418                 mov.w   #h'53EE, r2
.text:0005A41A                 add     r2, r1
.text:0005A41C                 mov     #1, r2
.text:0005A41E                 mov.b   r2, @(r0,r1)
.text:0005A420
.text:0005A420 loc_5A420:                              ; CODE XREF: army::ProcessDeath(int)+34↑j
.text:0005A420                                         ; army::ProcessDeath(int)+56↑j ...
.text:0005A420                 bsr     army::CancelAllSpells(void) ; end of block

и это:
Код: Выделить всё
sub_00448A40(iArmy->_f_514);
army::remove_binding(iArmy);
if ( !iArmy->activeSpellDuration[SPL_HYPNOTIZE] )
{
  if ( Random(1, 100) >= 60 )
  {
   if ( Random(1, 100) < 80 )
     *(&gpCombatManager->field_53DF - iArmy->side) = 1;
  }
  else
  {
   *(&gpCombatManager->heroSpellPower[2] + iArmy->side) = 1;
  }
}
v11 = 0;
activeSpellDuration = iArmy->activeSpellDuration;
do
{
  if ( *activeSpellDuration > 0 )
   army::CancelIndividualSpell(iArmy, v11);
  ++v11;
  ++activeSpellDuration;
}
while ( v11 < 81 );

army::CancelAllSpells(void) здесь инлайн. А Ваша, похоже, инлайн и выше. С другой стороны, какой-то короткой она получается. Может, в SoD разбили на две части?
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 30 ноя 2021, 02:35

Цитата:
Конец army тоже интересный


Я army восстановил. Скачайте версию 1.2 с гугл диска, у вас army какая-то странная.
Вернуться к началу

offlineАватара пользователя
void_17  
имя: имя
Ветеран
Ветеран
 
Сообщения: 548
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 132 раз.

Re: База данных IDA от void17

Сообщение void_17 » 30 ноя 2021, 02:37

AlexSpl писал(а):

Нашёл 0x514 поле army. Очень похоже на ?remove_aura@army@@QAAXXZ sub_448A40, убирает ауру.

Но такая функция уже есть в базе :smile5:

Смотрите на это:

Код: Выделить всё
.text:0005A3C2                 mov.l   #army::remove_aura(void), r0 ; end of block
.text:0005A3C2                                         ; end of block
.text:0005A3C4                 jsr     @r0 ; ?remove_aura@army@@QAAXXZ
.text:0005A3C6                 mov     r8, r4
.text:0005A3C8                 mov.l   #army::remove_binding(void), r0
.text:0005A3CA                 jsr     @r0 ; ?remove_binding@army@@QAAXXZ
.text:0005A3CC                 mov     r8, r4
.text:0005A3CE                 mov.w   #h'274, r0
.text:0005A3D0                 mov.l   @(r0,r8), r3
.text:0005A3D2                 tst     r3, r3
.text:0005A3D4                 bf      loc_5A420
.text:0005A3D6                 mov.l   #Random(int,int), r0
.text:0005A3D8                 mov     #100, r5
.text:0005A3DA                 jsr     @r0 ; ?Random@@YAHHH@Z
.text:0005A3DC                 mov     #1, r4
.text:0005A3DE                 mov     #60, r2
.text:0005A3E0                 cmp/gt  r0, r2
.text:0005A3E2                 bf      loc_5A3FA
.text:0005A3E4                 mov.l   #army::get_owning_side(void), r0
.text:0005A3E6                 jsr     @r0 ; ?get_owning_side@army@@QBAHXZ
.text:0005A3E8                 mov     r8, r4
.text:0005A3EA                 mov     #1, r3
.text:0005A3EC                 mov.l   #combatManager * gpCombatManager, r1
.text:0005A3EE                 mov.w   #21484, r2
.text:0005A3F0                 mov.l   @r1, r1
.text:0005A3F2                 add     r2, r1
.text:0005A3F4                 mov.b   r3, @(r0,r1)
.text:0005A3F6                 bra     loc_5A420       ; end of block
.text:0005A3F8                 nop
.text:0005A3FA ; ---------------------------------------------------------------------------
.text:0005A3FA
.text:0005A3FA loc_5A3FA:                              ; CODE XREF: army::ProcessDeath(int)+42↑j
.text:0005A3FA                 mov.l   #Random(int,int), r0
.text:0005A3FC                 mov     #100, r5
.text:0005A3FE                 jsr     @r0 ; ?Random@@YAHHH@Z
.text:0005A400                 mov     #1, r4
.text:0005A402                 mov     #80, r2
.text:0005A404                 cmp/gt  r0, r2
.text:0005A406                 bf      loc_5A420
.text:0005A408                 mov.l   #army::get_owning_side(void), r0
.text:0005A40A                 jsr     @r0 ; ?get_owning_side@army@@QBAHXZ
.text:0005A40C                 mov     r8, r4
.text:0005A40E                 mov     #1, r3
.text:0005A410                 mov.l   #combatManager * gpCombatManager, r1
.text:0005A412                 sub     r0, r3
.text:0005A414                 mov.l   @r1, r1
.text:0005A416                 mov     r3, r0
.text:0005A418                 mov.w   #h'53EE, r2
.text:0005A41A                 add     r2, r1
.text:0005A41C                 mov     #1, r2
.text:0005A41E                 mov.b   r2, @(r0,r1)
.text:0005A420
.text:0005A420 loc_5A420:                              ; CODE XREF: army::ProcessDeath(int)+34↑j
.text:0005A420                                         ; army::ProcessDeath(int)+56↑j ...
.text:0005A420                 bsr     army::CancelAllSpells(void) ; end of block

и это:
Код: Выделить всё
sub_00448A40(iArmy->_f_514);
army::remove_binding(iArmy);
if ( !iArmy->activeSpellDuration[SPL_HYPNOTIZE] )
{
  if ( Random(1, 100) >= 60 )
  {
   if ( Random(1, 100) < 80 )
     *(&gpCombatManager->field_53DF - iArmy->side) = 1;
  }
  else
  {
   *(&gpCombatManager->heroSpellPower[2] + iArmy->side) = 1;
  }
}
v11 = 0;
activeSpellDuration = iArmy->activeSpellDuration;
do
{
  if ( *activeSpellDuration > 0 )
   army::CancelIndividualSpell(iArmy, v11);
  ++v11;
  ++activeSpellDuration;
}
while ( v11 < 81 );

army::CancelAllSpells(void) здесь инлайн. А Ваша, похоже, инлайн и выше. С другой стороны, какой-то короткой она получается. Может, в SoD разбили на две части?



Лучше не берите не себя это дело. Займитесь пока другими функциями. Я приеду и посмотрю, исправлю. Я все кучу раз перепроверял, но мог все-таки где-то ошибиться.
Вернуться к началу

Пред.След.

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

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

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

cron