(30.04.2020 14:34)XEPOMAHT Wrote: [ -> ] (30.04.2020 13:46)Zur13 Wrote: [ -> ]Может товарищ Berserker или товарищ igrik, решаться взглянуть на проблему.
А что сам не сможешь написать удаление артефакта?
Вроде не сложно:
1. Получаем структуру героя.
2. Проверяем куклу героя и рюкзак на наличие артефакта. Можно вызовом, можно и ERM-ом.
3. Если нашли на кукле - вызов Hero_Delete_ArtFromSlot. Нашли в рюкзаке - вызов Hero_DeleteArtFromBackpack. Если просто удалить артефакт - вызов Hero_DeleteArt.
У меня в моде проблема решена. Но вот то что стандартные ЕРМ команды на удаление артефактов использовать нельзя это проблема.
Alex.Klive, надо проверить. Займусь.
igrik, баш с обновлением счётчика был же исправлен уже Н лет назад:
(* Fix HE:A3 artifacts delete - update art number *)
Core.ApiHook(@Hook_ErmHeroArt_DeleteFromBag, Core.HOOKTYPE_BRIDGE, Ptr($745051));
Core.ApiHook(@Hook_ErmHeroArt_DeleteFromBag, Core.HOOKTYPE_BRIDGE, Ptr($7452F3));
Code:
function Hook_ErmHeroArt_DeleteFromBag (Context: Core.PHookContext): longbool; stdcall;
const
NUM_BAG_ARTS_OFFSET = +$3D4;
HERO_PTR_OFFSET = -$380;
var
Hero: pointer;
begin
Hero := PPOINTER(Context.EBP + HERO_PTR_OFFSET)^;
Dec(PBYTE(Utils.PtrOfs(Hero, NUM_BAG_ARTS_OFFSET))^);
result := Core.EXEC_DEF_CODE;
end; // .function Hook_ErmHeroArt_DeleteFromBag
Ребят, проверьте по коду тестирования igrika. Сбойная команда — она HE:A3, которую я исправлял или HE:A, которую исправлю в противном случае.
(30.04.2020 18:32)Berserker Wrote: [ -> ]Ребят, проверьте по коду тестирования igrika. Сбойная команда — она HE:A3, которую я исправлял или HE:A, которую исправлю в противном случае.
Только что проверил 2.9.12 у меня баг воспроизводится и на HE-1:A3 и на HE-1:A-. Герой в редакторе карт установлен с 61 артефактами в рюкзаке и несколько надетых артефактов, скриптом удаляю из рюкзака топор кентавра (№7) одну штуку, и руками (не скриптом) кладу в рюкзак 5-7 артефактов снятых с куклы героя пока не появляется сообщение про полный рюкзак, после чего всё рюкзак работает только на изъятие.
Zur13, будь добр, скинь свою тестовую карту и скрипт.
Так, копнул я глубже и выяснилось вот что:
Zur13 правильно тут описывает проблему. Все дело в "дырах"
(30.04.2020 13:46)Zur13 Wrote: [ -> ]Как можно сломать?
После появления "дырки" в видимой области рюкзака появляется возможность положить в рюкзак больше 64 артефактов, просто складывая артефакты справа от "дырки". Соответственно при добавлении 65-го артефакта ломается структура героя в памяти и всё, причем поломка идет в сейв и все сейвы после поломки будут содержать сломанного героя.
При добавлении 65-го артефакта весь массив сдвигается, и 65й артефакт(2 по 4 байта) записывается в поля "кол-во артефактов"(1 байт), "пол"(4 байта), "настроена ли биография в редакторе"(1 байт), "биография". Отсюда и вылеты и разные казусы.
Код функции перемещения артефакта в рюкзак
PHP Code:
0x4E3200 bool8 __thiscall Hero_ArtAdd_InBackPack(_Hero_ *hero, _Art_ *art, int slot_in_backpack)
// slot_in_backpack =-1 - to Any
if ( hero->ArtsCount_inBackpack >= 64 )
return 0;
v3 = art->id;
if ( art->id == 3 || v3 == 4 || v3 == 5 || v3 == 6 )
return 0;
slot = slot_in_backpack;
if ( slot_in_backpack < 0 )
{
slot = 0;
art_in_slot = hero->Arts_inBackpack; // _Artifact_ backpack_art[64]
do
{
if ( art_in_slot->id == -1 )
break;
++slot;
++art_in_slot;
}
while ( slot < 64 );
}
if ( hero->Arts_inBackpack[slot].id != -1 )
{
k = 63;
last_slot = &hero->Arts_inBackpack[63]; // last slot art in backpack
while ( last_slot->id == -1 )
{
v8 = k--;
--last_slot;
if ( !v8 )
{
k = -1;
break;
}
}
if ( k >= slot )
{
next_art = &hero->Arts_inBackpack[k + 1];
j = k - slot + 1;
do
{
next_art->id = next_art[-1].id;
next_art->Mod = next_art[-1].Mod;
--next_art;
--j;
}
while ( j );
}
}
hero->Arts_inBackpack[slot] = *art;
++hero->ArtsCount_inBackpack;
return 1;
}
Поэтому нужно в HE:A и HE:A3 писать упаковку артефактов в рюкзаке, чтобы не было дыр.
Я в WND в диалоге сброса артефактов на землю писал такую упаковку (игнорируя то, что я частенько перекидываю тут пустое в пустое)
PHP Code:
// сжимаем порядок артефактов убирая все возможноые "дыры" между артефактами
int tmp_art = -1;
int tmp_mod = -1;
for(int i = 0; i<64; i++) {
for(int j = 63; j>=(i+1); j--) {
if(hero->backpack_art[j-1].id == -1 ) {
tmp_art = hero->backpack_art[j].id;
tmp_mod = hero->backpack_art[j].mod;
hero->backpack_art[j].id = hero->backpack_art[j-1].id;
hero->backpack_art[j].mod = hero->backpack_art[j-1].mod;
hero->backpack_art[j-1].id = tmp_art;
hero->backpack_art[j-1].mod = tmp_mod;
}
}
}
(30.04.2020 20:54)Berserker Wrote: [ -> ]Zur13, будь добр, скинь свою тестовую карту и скрипт.
Вот карта со встроенным скриптом на удаление артефакта из рюкзака. На старте карты показывается сообщение как сломать героя:
1. Открыть диалог героя
2. Нажать правую кнопку мыши на любом слоте артефакта
3. При этом удалится топор кентавра из видимого слота в рюкзаке.
4. Начать снимать артефакты с куклы героя и складывать их в рюкзак правее от "дыры" пока не появится сообщение что рюкзак героя полон.
5. После этого герой сломан, и в из рюкзака можно только извлекать артефакты но не ложить.
Иногда сообщение что рюкзак полон не появляется даже после снятия всех артефактов с куклы, можно проверить не сломан ли уже герой, или рестарт карты.
igrik, Zur13, спасибо за разъяснения, всё понял.
Daemon_n, доброе время суток! Я вот хочу понять можете пожалуйста разъяснить, про скрипт "Выбор режима типа битвы", это же удобная фишка зачем её вообще вырезать? Или я что-то не до понимаю. Перед боем есть выбор как ты хочешь биться, сам, быстрая битва(без маны).
[-] Скрипт "Выбор режима типа битвы" временно отключена (думаю, больше и не включу - просто вырежу в итоге:P )
Blacksmith, доброе утро!
Смена режима битвы (авто/вручную) делается на клавишу "W". АвтоБитва всегда будет без магии (в след релизе без маны), а переигровка её возвращает. Править скрипт смысла не вижу, так как мод Wog scropts должен оставаться готовым к обновлениям себя.
daemon_n, автобитва всегда без магии не самое удачное решение ИМХО. Часто с мистицизмом удобнее драться с магией, ведь это снижает потери (воскрешение к примеру). Мистицизм для мага мастхев. Получается, каждый раз переигровку делать?
Кстати, когда дерешься без маны и с зельем +10 атаки/без книги от фонтана удачи, не восстанавливается мана после битвы, ваше решение правит этот баг?
ElfbI,
1. Чаще у тебя нет мистицизма, чем он есть. Проблема в том, что в автобитве твой герой просто спамит всеми заклинаниями подряд. Да, переигровка для этого и сделана, чтобы переиграть, когда результат боя не устраивает, поскольку немного чаще, как я уже говорил, ману хочется сохранить. Могу попробовать сделать хоткей, который влияет на использование маны в автобое. Суть всего скрипта - экономия времени.
2. До этого мой скрипт забиоал книгу, но на её наличие завязано много скриптов, которые я не учел. Решение моё - отнимать ману и возвращать, если понадобится.
(04.05.2020 12:21)daemon_n Wrote: [ -> ]ElfbI,
1. Чаще у тебя нет мистицизма, чем он есть. Проблема в том, что в автобитве твой герой просто спамит всеми заклинаниями подряд. Да, переигровка для этого и сделана, чтобы переиграть, когда результат боя не устраивает, поскольку немного чаще, как я уже говорил, ману хочется сохранить. Могу попробовать сделать хоткей, который влияет на использование маны в автобое. Суть всего скрипта - экономия времени.
2. До этого мой скрипт забиоал книгу, но на её наличие завязано много скриптов, которые я не учел. Решение моё - отнимать ману и возвращать, если понадобится.
Ну мне например тоже удобнее диалог выбора режима битвы, возможен ли вариант когда переигровка битвы всегда ручная независимо от выбора в меню перед битвой? Возможно также отключение или наоборот включение показа диалога выбора режима битвы через меню настроек которое ПКМ на иконке настроек игры?
Zur13, я совсем не понял ни вопросы и ни их посыл.
Вог-Опция пока отключена. Верну, раз надо, но в текущем варианте тип битвы сменяется одно клавишей, моментально.
(04.05.2020 13:34)daemon_n Wrote: [ -> ]Zur13, я совсем не понял ни вопросы и ни их посыл.
Вог-Опция пока отключена. Верну, раз надо, но в текущем варианте тип битвы сменяется одно клавишей, моментально.
Извиняюсь стормозил насчет меню ПКМ и переигровки битвы.
В общем диалог выбора режима битвы нужно оставить, но его ВоГ опцию можно убрать если есть желание освобить место в ВоГ меню, так как этот диалог можно включить или отключить в меню настроек внутри игры при нажатии ПКМ на иконке настроек.
Только пока проверял на прошлой сборке 2.9.12, обнаружил что это меню неправильно дружит с переключением режима битвы клавишей W. Воспроизведение:
1. Стартуем карту,
2. Включаем диалог выбора режима битвы, через ПКМ меню на иконке настроек
3. Нападаем на кого-угодно выбираем битву в ручном режиме, и проводим бой
4. Отключаем диалог выбора режима битвы, через ПКМ меню на иконке настроек
5. Включаем режим быстрой битвы через клавишу W
6. Нападаем на кого-угодно и бой проходит в ручном режиме, хотя должен пройти в режиме быстрой битвы