Current time: 24.06.2017, 03:23 Hello There, Guest! (LoginRegister)
Language: english | russian  

Post Reply 
Threaded Mode | Linear Mode
Вопросы по моддингу
» (обсуждаем моддинг здесь)
Author Message
StasPV Offline

Posts: 90
Post: #451

Добрый вечер! Вопрос к программистам. Есть функция, которая определяет доход города (скопировано с базы ИДЫ Феанора):

Code:
//----- (005BFA00) --------------------------------------------------------
signed int __thiscall Town_GetGoldIncome(int this, char a2)
{
  signed int result; // eax@1
  int v3; // edi@1
  int v4; // esi@1
  int v5; // edx@9

  v4 = *(_DWORD *)(this + 336);
  v3 = *(_DWORD *)(this + 340);
  result = 500;
  if ( __PAIR__(
         (unsigned int)TownHallMask2 & *(_DWORD *)(this + 340),
         (unsigned int)TownHallMask & *(_DWORD *)(this + 336)) )
    result = 1000;
  if ( CityHallMask2 & v3 | CityHallMask & v4 )
    result = 2000;
  if ( CapitolMask2dword & v3 | CapitolMask & v4 )
    result = 4000;
  if ( a2 )
  {
    if ( ResSiloMask2 & v3 | (unsigned int)ResSiloMask & v4 )
    {
      v5 = *(_BYTE *)(this + 4);
      LOWORD(v5) = LOWORD(TownsResourceSilo[7 * v5 + 6]);
      result += v5;
    }
  }
  if ( __PAIR__((unsigned int)GrailMask2 & *(_DWORD *)(this + 348), (unsigned int)GrailMask & *(_DWORD *)(this + 344)) )
    result += 5000;
  return result;
}
// 66CDF0: using guessed type int TownHallMask;
// 66CDF4: using guessed type int TownHallMask2;
// 66CDF8: using guessed type int CityHallMask;
// 66CDFC: using guessed type int CityHallMask2;
// 66CE00: using guessed type int CapitolMask;
// 66CE04: using guessed type int CapitolMask2dword;
// 66CE6C: using guessed type int GrailMask2;
// 688F04: using guessed type int TownsResourceSilo[63];

Первый вопрос, как правильно понимать данное условие:
Code:
if ( __PAIR__(
         (unsigned int)TownHallMask2 & *(_DWORD *)(this + 340),
         (unsigned int)TownHallMask & *(_DWORD *)(this + 336)) )
, вижу что проверка на построенный таунхолл, но что именно происходит в условии не понимаю.

Второй вопрос, как с помощью длл добавить еще одно условие перед return result: если город Темница, и построен торговец артефактами то доход +100? У меня есть скрипт, который писал на ЕРМ, он просчитывает количество темниц, проверяет постройку здания, а потом прибавляет залото в начале хода, но хочеться научиться писать подобные штуки в Microsoft Visual C++, кроме того есть планы модифицировать под себя еще кое-какие функции, но очень нужен хоть один пример, по аналогии с которым я бы потихоньку начал разбираться дальше
(This post was last modified: 05.06.2016 00:03 by StasPV.)
04.06.2016 23:57
Find all posts by this user Quote this message in a reply
gamecreator Offline
Administrators

Posts: 7094
Post: #452

На место return result; вставить хук и изменить этот самый result. В ERM это через erm hooker делается, а в плагине просто вместо возврата записываешь прыжок на твою функцию, которая __declspec(naked), и там уже изменяешь и возвращаешь результат. Сходу код не могу выдать, это надо с адресами копаться (посмотреть где result, куда вписывать хук и т.п.). Тут же важно ещё и понимать язык ассемблера, одного знания С++ недостаточно.
А что за база Феанора? Можно ссылку?


When all gods have burnt to ashes in eternity of sorrow,
Demons gonna tear your soul because there is no tomorrow.
05.06.2016 00:25
Find all posts by this user Quote this message in a reply
StasPV Offline

Posts: 90
Post: #453

[b]ссылка с df2 форума на базу Феанора

Quote:Сходу код не могу выдать
сходу не надо, если вдруг время будетAb
05.06.2016 00:49
Find all posts by this user Quote this message in a reply
StasPV Offline

Posts: 90
Post: #454

По той функции дохода из поста выше. Утром набросал ерм скрипт, в котором ставлю хук и изменяю result. Скрипт записывает в result 5000.

Теперь голову ломаю, как считать номер города и флаг здания, чтоб добавить условие... здесь моих знаний пока не хватает

05.06.2016 13:18
Find all posts by this user Quote this message in a reply
igrik Offline
Moderators

Posts: 1112
Post: #455

Ты поставил хук, на место добавления золота при настроенном граале. Поэтому лучше вместо установки

сделать добавление

При этом, насколько я понимаю, если грааль не построен, то и золота от твоего хука не прибавится


Скачать HoMM3 ERA 2.461
И пара мелочей для ERA
(This post was last modified: 05.06.2016 14:59 by igrik.)
05.06.2016 14:58
Visit this user's website Find all posts by this user Quote this message in a reply
StasPV Offline

Posts: 90
Post: #456

igrik, то пробный скрипт, поэтому записывал сразу значение 5000, позже изменил на +5000, чтоб проверить работает ли. Хук установлен на адрес с уже окончательным доходом, вроде подсчитывает правильно и с граалью и без.

Тут на дф2 нашел запись по структурам монстров и героев, а вот по городу ничего найти не могу, не знаю от куда прочитать тип города и построенные в нем строения
05.06.2016 15:12
Find all posts by this user Quote this message in a reply
gamecreator Offline
Administrators

Posts: 7094
Post: #457

Хук поставлен правильно.
Структура города (из исходников ВоГ):
Code:
// Замки
// 6971F0 (18h*9[число типов городов])
// 6A60B0 ()
//
// + 24h dw * 8  = количество доступных для найма монстров
// +150h dd + dd = постройки
// 0 01 -  0 Гильдия магов ур 1
//   02 -  1 2
//   04 -  2 3
//   08 -  3 4
//   10 -  4 5,?(6,7)
//   20 -  5 таверна
//   40 -  6 верфь(0,4,7,8),?(1,2,3,5,6)
//   80 -  7 форт (+ слева картинка)
// 1 01 -  8 цитадель (+)
//   02 -  9 замок (+)
//   04 - 10 управа (+)
//   08 - 11 префектура (+)
//   10 - 12 муниципалитет (+)
//   20 - 13 капитолий (+)
//   40 - 14 рынок
//   80 - 15 хранилище ресурсов
// 2 01 - 16 кузница
//   02 - 17 маяк(0),таинств.пруд(1),торг.арт.(2,5,8),?(3),вуаль тьмы(4),
//           чер.ход(6),кл.бог.войны(7)
//   04 - 18 баст.гриф.(0-3),гильд горн.(1-2),крылья воятеля(2-2),инкуб(3-1),
//           взрыт.мог.(4-1),гриб.кольца(5-1),стол(6-1),кв.капитана(7-1),сад жизни(8-1)
//   08 - 19 баст.гриф.+(0-3+),гильд горн.(1-2+),крылья воятеля(2-2+),инкуб(3-1+),
//           взрыт.мог.(4-1+),гриб.кольца(5-1+),стол(6-1+),кв.капитана(7-1+),сад жизни(8-1+)
//   10 - 20 ?(0,1,2,3,4,5,6,7,8)
//   20 - 21 конюшни(0),фонтан уд(1),см.башня(2),сер.тучи(3),ус.ч.магии(4),
//           водов.маны(5),гил.н.раб(6),знаки страха(7),ун.магии(8)
//   40 - 22 бр.меча(0),сокровищ(1),библ(2),врата замка(3),преобр.ск(4),
//           портал выз(5),дв.балист(6),обелиск крови(7),?(8)
//   80 - 23 ?(0,1,4,7,8),стена зн.(2),орден огня(3),ак.б.иск(5),храм волх(6)
// 3 01 - 24 ?(0,2,4,5,6,7,8),мол.дендр(1-5),клетки(3-3)
//   02 - 25 ?(0,2,4,5,6,7,8),мол.дендр(1-5+),клетки(3-3+)
//   04 - 26 грааль
//   08 - 27 ?(x)
//   10 - 28 ?(x)
//   20 - 29 ?(x)
//   40 - 30 жил 1  (x-1)
//   80 - 31 жил 2  (x-2)
// 4 01 - 32 жил 3  (x-3)
//   02 - 33 жил 4  (x-4)
//   04 - 34 жил 5  (x-5)
//   08 - 35 жил 6  (x-6)
//   10 - 36 жил 7  (x-7)
//   20 - 37 жил 1+ (x-1+)
//   40 - 38 жил 2+ (x-2+)
//   80 - 39 жил 3+ (x-3+)
// 5 01 - 40 жил 4+ (x-4+)
//   02 - 41 жил 5+ (x-5+)
//   04 - 42 жил 6+ (x-6+)
//   08 - 43 жил 7+ (x-7+)
// +158h dd + dd = модификаторы и производители существ
// теже жилища
// 0 80 - форт слева картинка
// 2 08 - "Инкубатор"
// 3 40 - "Бесы" карт
//   80 - "Гоги"
// 4 01 - "Адские Гончие"
//   02 - "Демоны"
//   04 - "Порождение Зла"
//   08 - "Эфриты"
//   10 - "Дьяволы"
//   20 - + "Черти" ("Бесы")
//   40 - + "Магоги" ("Гоги")
//   80 - + "Церберы" ("Адские Гончие")
// 5 01 - + "Рогатые Демоны" ("Демоны")
//   02 - + "Адские Отродья" ("Порождение Зла")
//   04 - + "Султаны Эфритов" ("Эфриты")
//   08 - + "Архидьяволы" ("Дьяволы")

struct _CastleSetup_{
  Byte   Number;        //* +0 0,1,2,...
  char   Owner;         //*O +1 0,...
  char   BuiltThisTurn; // +2 - уже строили в этот турн (0-нет, 1-да, 2-не наш город)
  Byte  _u2;            //* +3 0
  Byte   Type;          //*T +4 0,1...,8
  Byte   x;             //* +5
  Byte   y;             //* +6
  Byte   l;             //* +7
  Byte   Pos2PlaceBoatX;//* +8 помещать лодку при покупки в Shipyard
  Byte   Pos2PlaceBoatY;//* +9
  Byte  _uAa[2];        // +0A
  int    IHero;         //* +0Ch = номер героя внутри города (-1 - никого нет)
  int    VHero;         //* +10h = номер героя снаружи города (-1 - никого нет)
  char   MagLevel;      //*G +14h = уровень магической гильдии в городе (исп. AI для постройки)
  Byte  _u15;
  Word   Monsters[2][7];//*M- +16h ко-лво простых и апгрейднутых
  char  _u32;           //*- +32 = ?
  char  _u33;           //* +33 = 1
  char  _u34;           //* +34 = 0
  Byte  _u35a[3];
  int   _u38;           //* +38 = -1
  int   _u3C;           //* +3C = -1
  short _u40;           //*- +40
  Word  _u42;           //  +42
  int    Spels[5][6];   //*G- +44 сами заклинания
  char   MagicHild[5];  //*G- +BCh = колво заклинаний в уровне гильдии
  Byte  _uC1[3];
  char  _uC4;           //* +C4 = 0
  Byte  _uC5[3];
  _AMes_ Name;          //*N +C8 -> Имя города
  int   _u8[3];         //* +D4 = 0
  Dword  GuardsT[7];    //*M +E0 = охрана замка
  Dword  GuardsN[7];    //*M +FC = кол-во охраны
  Dword  GuardsT0[7];   //*M- +118 = охрана замка
  Dword  GuardsN0[7];   //*M- +134 = кол-во охраны
  Byte   Built[8];      //*B +150h = уже построенные здания (0400)
  Byte   Bonus[8];      //*B +158h = бонус на существ, ресурсы и т.п., вызванный строениями
  Dword  BMask[2];      //*B- +160h = маска доступных для строения строений
};


When all gods have burnt to ashes in eternity of sorrow,
Demons gonna tear your soul because there is no tomorrow.
05.06.2016 15:45
Find all posts by this user Quote this message in a reply
igrik Offline
Moderators

Posts: 1112
Post: #458

Всё таки хук поставлен не правильно. Потому что в этом месте уже не получить структуру города внутри этой функции, и поэтому ни номер города на карте, ни его тип.
Хук нужно ставить в 0x005BFA68.


Скачать HoMM3 ERA 2.461
И пара мелочей для ERA
(This post was last modified: 05.06.2016 18:14 by igrik.)
05.06.2016 18:13
Visit this user's website Find all posts by this user Quote this message in a reply
StasPV Offline

Posts: 90
Post: #459

Пока получилась такая штука:


Стабильно вылетает в первую неделю, хотя после того как переустановил героев вылетают подряд все скрипты, и старые и новые, может кто-нибудь проверить у себя на вылеты?

Единственное, не могу понять, почему тип города определяется только на карте, если клацнуть на замок, а в экране города значение всегда 0, как и при передаче хода.

igrik, только прочитал твое сообщение, сейчас попробую.
(This post was last modified: 05.06.2016 18:48 by StasPV.)
05.06.2016 18:45
Find all posts by this user Quote this message in a reply
gamecreator Offline
Administrators

Posts: 7094
Post: #460

igrik, да, насчёт структуры города ты прав. Не заметил, что значение затирается.


When all gods have burnt to ashes in eternity of sorrow,
Demons gonna tear your soul because there is no tomorrow.
05.06.2016 18:56
Find all posts by this user Quote this message in a reply
StasPV Offline

Posts: 90
Post: #461

igrik, твой скрипт работает на ура, спасибо. Еще раз посмотрел в ИДЕ, увидел, что уже при проверке на хранилище ресурсов используется esi.

gamecreator, спасибо за структуру города.
(This post was last modified: 05.06.2016 19:09 by StasPV.)
05.06.2016 19:07
Find all posts by this user Quote this message in a reply
igrik Offline
Moderators

Posts: 1112
Post: #462

Подскажите, человеку вообще слабознакомому с С++.
Как это (хоть и работающее) безобразие привести к нормальному виду. А еще лучше оранизовать в функцию и показать способ вызова этой функции, которая будет возвращать адрес структуры активного стека. И еще желательно не через __thiscall.
Code:
char* combatManager = (char*)(*((int*)0x699420));  // это this_

int j = *(int*)(this_ + 78524);       // номер активного стека текущей стороны 0 ... 20
int i = *(int*)(this_ + 78520);       // номер активной стороны
int v3 = i * 14 + i * 7 + j;          // переход к номеру стека 0 ... 41
int v1 = v3 * 1352;                   // длина структуры одного стека
int v2 = *(int*)(this_ + 21708 + v1); // получить структуру стека


Скачать HoMM3 ERA 2.461
И пара мелочей для ERA
01.07.2016 14:57
Visit this user's website Find all posts by this user Quote this message in a reply
gamecreator Offline
Administrators

Posts: 7094
Post: #463

Что подразумевается под нормальным видом? Потому что лично для меня нормальным было бы подобное:
Code:
CombatManager *cm = *(CombatManager**)0x699420;
BattleStack activeStack = cm->stack[cm->currentSide][cm->currentSideStack];
Но к такому виду приводить долго и нудно.
И зачем здесь функция?


When all gods have burnt to ashes in eternity of sorrow,
Demons gonna tear your soul because there is no tomorrow.
01.07.2016 18:14
Find all posts by this user Quote this message in a reply
Berserker Offline
Administrators

Posts: 10163
Post: #464

Code:
void* __stdcall getActiveStackAddress () {
  char* combatManager = (char*)(*((int*)0x699420));  // это this_

  int j = *(int*)(this_ + 78524);       // номер активного стека текущей стороны 0 ... 20
  int i = *(int*)(this_ + 78520);       // номер активной стороны
  int v3 = i * 14 + i * 7 + j;          // переход к номеру стека 0 ... 41
  int v1 = v3 * 1352;                   // длина структуры одного стека
  int v2 = *(int*)(this_ + 21708 + v1); // получить структуру стека
  return (void*) v2;
}


Если возвращать адрес нужно как целое число, то просто return v2; и int __stdcall getActiveStackAddress .
02.07.2016 14:47
Find all posts by this user Quote this message in a reply
feanor Offline

Posts: 476
Post: #465

igrik, у тебя же есть человеческие заголовочники из HD.
o_BattleMgr->GetCurrentStack();
03.07.2016 01:59
Find all posts by this user Quote this message in a reply
« Next Oldest | Next Newest »
Post Reply 


Forum Jump:

Powered by MyBB Copyright © 2002-2017 MyBB Group