A general function for removing an artifact from a given slot would be good.
The erm combination HE:A1 + HE:A2 almost serves the part FU(UnequipArtFromSlot) missing, yet HE:A doesn't allow defining a particular slot for art removal
Quote:В ERA+ как раз занимаюсь добавлением в HE:A поддержки рюкзака героя. Включая открытие этого самого рюкзака из любого места игры (порт с MoP).
Cool feature

Berserker, не подскажешь адрес по которому WOG устанавливает все свои основные патчи и хуки (где-то между срабатыванием заплаток BeforeWoG и AfterWoG)
Их плагин HD мода ставит, перехватывая управление вогом, там адрес динамический.
А так тебе нужна Initialize из _B1.cpp по адресу 701215
Code:
Dword Initialize_P=0;
void Initialize(void)
{
int i,j;
long del;
Byte *s,*d;
Initialize_P=(Dword)ForAK; // to prevent removing of ForAK
StartDLLService();
if(LoadZVSDialogs()) return /*Exit()*/;
// CommonDialog("Hi from a Heroes3 extension!");
// START("Start Up Initialization");
//InitWoGSetup();
//UseWogSetup(&DlgSetup);
for(i=0;;i++){
if(Accessers[i].where==0) break;
s=(Byte *)&Accessers[i].what;
d=(Byte *)Accessers[i].where;
for(j=0;j<Accessers[i].len;j++) *d++=*s++;
// *(long *)(Accessers[i].where)=Accessers[i].what;
#ifdef DEBUG
if(DebugDPNum<DSNUM){
if(Accessers[i].remember!=0){
for(j=0;j<16;j++){
char c=Accessers[i].remember[j];
DebugDP[DebugDPNum].name[j]=c;
if(c==0) break;
}
DebugDP[DebugDPNum].dp[0]=(Dword)Accessers[i].what;
DebugDP[DebugDPNum].dp[1]=(Dword)Accessers[i].what+Accessers[i].size;
++DebugDPNum;
}
}
#endif
}
for(i=0;;i++){
if(Copiers[i].from==0) break;
j=Copiers[i].len;
do{ *Copiers[i].to++=*Copiers[i].from++; --j; }while(j!=0);
}
for(i=0;;i++){
if(Callers[i].where==0) break;
if(Callers[i].fnew==0) continue; // если новый указатель=0, то пропустим
del=Callers[i].fnew-Callers[i].where-5;
*(long *)(Callers[i].where+1)=del;
#ifdef DEBUG
if(DebugDPNum<DSNUM){
if(Callers[i].remember!=0){
for(j=0;j<16;j++){
char c=Callers[i].remember[j];
DebugDP[DebugDPNum].name[j]=c;
if(c==0) break;
}
DebugDP[DebugDPNum].dp[0]=(Dword)Callers[i].fnew;
++DebugDPNum;
}
}
Спасибо.
Вечно запариваюсь какие параметры хука использовать, если ида не указывает соглашение о вызове.
Поэтому просто оставлю это здесь, как памятку.
Code:
void Initialize(void) 0x701215 // в исходниках
signed int sub_701215() // в иде
_PI->WriteHiHook(0x701215, SPLICE_, SAFE_, CDECL_, WoGInitialize);
It is a little bit surprising to find out that IF:M breaks the mouse click/release event
Try this code:
What you want to do is to click on the first town of the list (item 32). You get a IF:M msg show correct item ID. And then try to click on anywhere of the Adventure map, you will again get the msg saying mouse item is 32, which is wrong (should be 37).
This is because in the mouse event was interupted by the frist IF:M and the "mouse release" part of the event was only triggered when we click the second time. It is understandable, but kinda surprising.
(06.02.2023 19:05)Archer30 Wrote: [ -> ]Try this code:
In ERA+ code working correct:
always 37 on adventure map click.
Berserker, apologize for my miss. My code was more complicated than this, when I tested it, it produced error. And something magically happened when I extract the "problematic code", it just stopped being problematic
Okay I have another finding:
It looks like SN:F^GetGameState^ is useless. It seems only returns the y3 value (of SN:L A E) which is always 4205280 (Adv Map Screen) no matter what exactly the screen we are on. This defeats the purpose of using this command.
Archer30,
!!SN:F^GetGameState^/?y1/?y2;
!!IF:M^%y1 %y2^;
y1 always map, y2 current dlg
Great!

Did not know it has a second argument as well
(08.02.2023 00:29)Archer30 Wrote: [ -> ]Bug report: AotD does not work for defending AI
In order to reproduce, just follow the steps
- use the erm
- pick one AI hero to fight
- find out the AI hero does not cast AotD spells
!!HE:A4 не оденет артефакт на куклу героя, если слот на кукле занят другим артефактом, включая заблокированные слоты. Артефакт будет добавлен в сумку, из которой автокаст не работает. Для 100% одевания артефакта сначала нужно раздеть героя, а потом уже что-то одевать.
И не стоит забывать, что автокаст от артефактов работает именно на ходе первого монстра со стороны героя, имеющего на кукле соответствующий артефакт.
Quote:!!HE:A4 не оденет артефакт на куклу героя, если слот на кукле занят другим артефактом, включая заблокированные слоты. Артефакт будет добавлен в сумку, из которой автокаст не работает. Для 100% одевания артефакта сначала нужно раздеть героя, а потом уже что-то одевать.
Thanks
For some reason, I want to kill myself now. "Report" removed.
Please, don't kill yourself. We need you

Don't worry, if I can get some help with this matter
debug
A player reported this error about "no space in buffer". What does that mean? Looking for some general info and advice how to fix the problem
Edit: I start to wonder if the player had submitted a wrong debug folder for this problem, because it shows another problem that I had indentified.
Well, in this case, I still wonder how to resolve the problem from the debug. It was resulted by my "fix" to the first acting stack on the battlefield. It is sometimes not correct and thus I correct it by erm.
I wonder if there is a better solution, if my script can't work correctly.
It's not yet found what cause the error, but very likely, it's Majaczek's plugin )))
(08.02.2023 04:09)Archer30 Wrote: [ -> ]
По скрипту сразу видно отсутствие проверки на неинициализированные стеки. В итоге в переменную (speed:y) может записаться мусор. Так же нет проверки на стрелковые башни, в итоге - так же может затесаться мусорный результат функции.
Ну и сама запись "!!VRi^tum_firstStackFixed^:S(TRUE);" мне вообще не понятна. При чём тут тип переменных "i", которых и так кот наплакал? Используй старый добрый тип переменных "v".