Полная Версия: (sfall) дополнения
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25
Fakeman
Ок, гляну в чем там у меня проблема. Помню что вроде как работало, а вчера тык-мык уже не работает.

Отправлено: 12 ноя 17 16:59
В общем это не у меня проблема, а в движке, я не знаю как ты там тесты проводишь, что у тебя ничего не получается с ними) — то мобы у тебя тоже почему то сами себя не бьют.
В общем рассказываю как надо правильно делать тесты, берешь чистый фол без всяких сфалов меняешь скрипт DUDEку, тупо можно без логики с процедурой map_exit_p_proc с простым display_msg("map_exit_p_proc");
Начинаешь новую игру и смотришь, что при заходе в храм, не срабатывает обработчик выхода из карты.
Далее новая игра сохраняемся-загружаемся, входим в храм обработчик срабатывает но только 1 раз пока не сделаем загрузку игры.
Crafty
QUOTE (Fakeman)
Начинаешь новую игру и смотришь, что при заходе в храм, не срабатывает обработчик выхода из карты.
Далее новая игра сохраняемся-загружаемся, входим в храм обработчик срабатывает но только 1 раз пока не сделаем загрузку игры.
Да, это увидел сразу (для моего теста выход/возврат из/в пещер[ы]), но map_exit_p_proc всё равно будет срабатывать позже (в том же Кламате для моего теста, то есть не будет ситуации "последующие выходы в текущей сессии игры не вызывают данный обработчик.", а то я сначала решил что вообще перестанет срабатывать).
С некоторыми картами (или ситуациями) действительно фигня — убирается скрипт ГГ из списка скриптов персонажей до вызова map_exit_p_proc (для стартовой можно в acklint добавить сообщение и увидеть что для него срабатывает всегда при заходе в храм).
Смирись, kek ;)
Fakeman
QUOTE
но map_exit_p_proc всё равно будет срабатывать позже (в том же Кламате для моего теста

А от чего это будет зависить, что позже сработает?
может эту особеность поведения можно где-нибудь применить.
Crafty
QUOTE (Fakeman)
А от чего это будет зависить, что позже сработает?
может эту особеность поведения можно где-нибудь применить.
Баг это, а не особенность :-p
Fakeman
Еще такой вопрос меняю пид в движке для сенсора на ACTIVE_MOTION_SENSOR (208) а игра почему-то говорит что в руке не установлен сенсор, т.е. вообще перестает работать и для пида MOTION_SENSOR
Меняю так.
CODE
     
write_byte(0x41BBFC, PID_ACTIVE_MOTION_SENSOR);
write_byte(0x41BC12, PID_ACTIVE_MOTION_SENSOR);
write_byte(0x4794AF, PID_ACTIVE_MOTION_SENSOR);
write_byte(0x4C09BC, PID_ACTIVE_MOTION_SENSOR); //for worldmap

Там почему-то 1 байт отводится под пид и что-то у меня такое впечатление что число 208 он считает отрицательным, такое вообще бывает в ассеблере?
Или где-то еще есть и оно не указанно.
Crafty
QUOTE (Fakeman)
Еще такой вопрос меняю пид в движке для сенсора на ACTIVE_MOTION_SENSOR (208) а игра почему-то говорит что в руке не установлен сенсор, т.е. вообще перестает работать и для пида MOTION_SENSOR
Так в руке у тебя всё так же остаётся сенсор с PID_MOTION_SENSOR. Движок не использует PID_ACTIVE_MOTION_SENSOR.
QUOTE (Fakeman)
Там почему-то 1 байт отводится под пид и что-то у меня такое впечатление что число 208 он считает отрицательным, такое вообще бывает в ассеблере?
Бывает, но не в этом случае — там нет знаковой проверки.
QUOTE (Fakeman)
Или где-то еще есть и оно не указанно.
Какая-то адская задумка... :-p
Fakeman
CODE
Так в руке у тебя всё так же остаётся сенсор с PID_MOTION_SENSOR. Движок не использует PID_ACTIVE_MOTION_SENSOR.

У меня использует) а у тебя просто старый движок :P
Ложу в руку актив сенсор или меняю так
write_int(objectPtr + 0x64, PID_ACTIVE_MOTION_SENSOR);
QUOTE

Бывает, но не в этом случае — там нет знаковой проверки.

Думаю, он тут считает до 127, остальное отрицательными числами считает
вот смотри разница кода между счетчиком и сенсером.
CODE

cmp     eax, PID_ACTIVE_GEIGER_COUNTER
неx: 3D CF 00 00 00

CODE
cmp     eax, PID_MOTION_SENSOR
неx: 83 F8 3B

Чуешь разницу)

QUOTE
Какая-то адская задумка... :-p

надо актив_сенсор переместить на пид <128 число, и узнаем какая это задумка.
Crafty
QUOTE (Fakeman)
Чуешь разницу)
2 байта :-p
Но [не]знаковость определяется следующей (как правило) командой (или командами) — jb != jl.
Fakeman
Я тебе не тот код нарисовал, но суть не поменялась, один байт под пид, когда нужно 2 минимум.
Дальше там jz проверка — перехода нет, значит сравниваемые операнды не равны.
С пид меньше 128 все отлично.
Видимо компилятор не тот машинный код с генерировал для движка.
Узнай как работает этот машинный код, 3В — это пид.
CODE
83 78 64 3B

это все тот же cmp eax+iobj.pid, PID_ но у них разный машинный код.
Crafty
QUOTE (Fakeman)
это все тот же cmp eax, PID_ но у них разный машинный код.
Без разницы:
QUOTE
Чаще всего используемая инструкция сравнения — это команда CMP. Она сравнивает операнды и изменяет регистр флагов.

Таблица 1.1. Регистр флагов
Номер бита | Название | Описание
0                  CF             Флаг переноса
6                  ZF            Флаг нулевого результата
7                  SF             Флаг знака результата
11                OF             Флаг переполнения

Таблица 1.5. Команды условных переходов
Команда | Условие | Условие
JB            X < Y        CF = 1
JL            X < Y        SF! = OF
JZ            X = Y        ZF = 1
Fakeman
QUOTE
это команда CMP. Она сравнивает операнды и изменяет регистр флагов.

А где в вашей табличке флаг ZF ? — она его меняет(уст. в 1) если результат сравнения равен 0, т.е. если операнды равны.
Crafty
QUOTE (Fakeman)
А где в вашей табличке флаг ZF ? — она его меняет(уст. в 1) если результат сравнения равен 0, т.е. если операнды равны.
Всю таблицу нужно было скопировать? Добавил :-p
Fakeman
Добавил молодец)
Теперь разбирайся почему не устанавливается флаг ZERO если второй операнд больше 127 :)
CODE
cmp     [eax+iobj.pid], PID_ACTIVE_MOTION_SENSOR
jz      short loc_41BC17

Crafty
QUOTE (Fakeman)
Теперь разбирайся почему не устанавливается флаг ZERO если второй операнд больше 127 :)
Для jz без разницы больше или меньше — она выполнится если оба операнда равны.
У тебя pid объекта (который [eax+iobj.pid]) не равен PID_ACTIVE_MOTION_SENSOR или у переменной MotionScannerFlags установлен первый бит (Allow sensor use on automap when motion sensor is in pack rather than hands) и в этом случае игнорируется изменяемый тобою код (а именно write_byte(0x41BBFC, PID_ACTIVE_MOTION_SENSOR);).
Fakeman
В сфале стоит дефолтное для движка поведение.
Если я записываю другой пид write_byte(0x41BBFC, 100) то этот предмет становится как датчик.
Да тут явно проц считает что ему дают отрицательное число для сравнения, поэтому в операции сравнения не уст флаг zero. Не зря же там разные машинные коды.
Crafty
QUOTE (Fakeman)
Не зря же там разные машинные коды.
Как скажешь ;)
Fakeman
Смотри из движка.
CODE
00411231 cmp     eax, 0FFFFFFFEh
нех opcode: 83 F8 FE

это же число -2, а не 4294967294, хотя это так-же можно считать числом 254.

В общем везде где нужно сравнить число больше 7F в исходниках используется не одно байтовый второй операнд.
Crafty
QUOTE (Fakeman)
это же число -2, а не 4294967294, хотя это так-же можно считать числом 254.
Поэтому и важно какая команда идёт следом — для jl = -2, а для jb = 254.
Часто использую этот трюк обработки — к примеру, в движке проверка правильности скилла сделана как для знакового операнда и выглядит так:
CODE
 test eax, eax // или если удобнее cmp  eax, 0
 jl   .fail // меньше 0
 cmp  eax, 18
 jl   .success // меньше 18
.fail: // eax содержит неправильный скилл, то есть не в пределах 0-17 (SKILL_SMALL_GUNS-SKILL_OUTDOORSMAN)
.success: // eax содержит правильный скилл

Вместо этого достаточно обрабатывать как для беззнакового:
CODE
 cmp  eax, 18
 jb   .success // 0-17
.fail:
.success:

Но в твоём случае (jz) это не существенно:
QUOTE
###  Команда CMP #########################################################

### Производит  сравнение операндов, вычитая  из первого  операнда  второй.
При этом операнды остаются без изменения.

### Устанавливает  флажки  CF,  AF,  SF,  ZF,  PF,  OF  в  соответствии  с
результатом операции. Причем флажки  CF и  AF становятся  флажками  заема и
устанавливаются в 1, если вычитаемое больше уменьшаемого.

В конце-то концов напиши маленький компилируемый пример своего скрипта :-p
Fakeman
Я же написал пример, логика скрипта вообще тут не важна.
CODE

write_byte(0x41BBFC, PID_ACTIVE_MOTION_SENSOR);
write_byte(0x41BC12, PID_ACTIVE_MOTION_SENSOR);

Подставляем любой пид больше 127, ложим этот предмет в руку открываем карту и нажимаем кнопку "сканер", игра будет думать что указанного предмета в руке нет.
Заменим на любой пид меньше 128 и пробуем, все работает.
Короче забей.

Crafty
QUOTE (Fakeman)
Короче забей.
Таки ты прав, снимаю шляпу :)
Я затупил и не раглядывал опкоды, а там же dword (write_byte заманипулировал) сравнение и этот байт "разворачивается" в знаковое двойное слово если больше 127 (208 в 0xFFFFFFD0 или 4294967248). Не повезло, что PID_MOTION_SENSOR=59, а был бы больше 127 и компилятор сразу сгенерировал бы более универсальный код для тёмных делишек:
CODE
81 78 64 D0 00 00 00          cmp  [eax+iobj.pid], PID_ACTIVE_MOTION_SENSOR

Fakeman
Такс у меня новая проблема.
Когда используешь какой-либо предмет (пиктограмма руки) из открытого инвентаря игрока, то этот предмет нельзя удалить, что-то блокирует по видимому его в движке, destroy_object(itemptr) как бы его удаляет, но предмет остается в инвентаре, и если выйти на глобал и зайти обратно то на месте этого предмета образуется всякий мусор(может стена появиться, или криттер какой-нибудь), но в итоге игра потом крашится.
В данный момент удаление происходит в хуке HOOK_USESKILL, и требуется удалить израсходованную аптечку которую использует игрок.
В общем какие скриптовые манипуляции нужно сделать что-бы двиг корректно удалил предмет, как он это делает в случае когда когда используешь аптечки.

В хуках HOOK_USEOBJ/HOOK_USEOBJON есть возможность удалить такой предмет.
CODE
int     ret1 - overrides hard-coded handler and selects what should happen with the item (0 - place it back, 1 - remove it, -1 - use engine handler)

Вот мне надо тоже самое проделать только скриптово.
Crafty
QUOTE (Fakeman)
В общем какие скриптовые манипуляции нужно сделать что-бы двиг корректно удалил предмет, как он это делает в случае когда когда используешь аптечки.
rm_obj_from_inven(source, item) перед destroy_object(item), не?
Fakeman
Нет) тоже самое будет, если использовать другую функцию которая удаляет несколько экземпляров то она возвратит 0. Что-то в движке не дает удалить этот предмет.
Я уже напрямую использовал двиг.функцию _destroy_obj и без результата.
Crafty
QUOTE (Fakeman)
Нет) тоже самое будет, если использовать другую функцию которая удаляет несколько экземпляров то она возвратит 0. Что-то в движке не дает удалить этот предмет.
rm_mult_objs_from_inven возвращает 0 если в инвентаре нет нужного предмета. И его нет, потому что "Когда используешь какой-либо предмет (пиктограмма руки) из открытого инвентаря игрока" то движок временно из инвентаря его удаляет. И в зависимости от результата использования или возвращает в инвентарь (0 — place it back) или удаляет фактически (1 — remove it).
Попробуй перехватывать HOOK_USEOBJ/HOOK_USEOBJON, сохранять какой предмет используется и проверять его в HOOK_USESKILL, а если совпадают то устанавливать любую свою переменную чтобы в HOOK_USEOBJ/HOOK_USEOBJON она проверялась и если нужно меняй код возврата на 1 (remove it).
Fakeman
Я и так сохраняю указатель из хука при использовании, потом этот указатель в useskill использую, но проблема то в том что ноок использования отрабатывает до ноока скила.
Ладно я кажись понял как его удалить, те получается нужно удалять после отработки useskill.
Fakeman
Вот новый косяк, при использовании предмета через контекстное меню рюкзака(пиктограмма), если таковых предметов в стопке имеется несколько штук, то эти все предметы(в стопке) имеют один указатель, и при уменьшении у предмета в стопе заряда, заряды уменьшается сразу у всех предметов в стопки (помнится ты об этом говорил, когда речь шла об износе предметов).
В общем как узнать сколько лежит предметов в такой стопке?

Или может есть какой-то механизм отделения их друг от друга)
Fakeman
проблема решена, уже есть такая функция
QUOTE
В общем как узнать сколько лежит предметов в такой стопке?

obj_is_carrying_obj
Fakeman
CODE
addnamedhandler("iSeeYouInCombat", iSeeYouInCombat); // не addnamedevent!

О перечитывал тему и увидел такое, а в чем отличие AddNamedHandler от AddNamedEvent ?
Crafty
QUOTE (Fakeman)
О перечитывал тему и увидел такое, а в чем отличие AddNamedHandler от AddNamedEvent ?
Event после срабатывания удаляется, а Handler существует до удаления с помощью ClearNamed.
Можно и с Event (но это лишние затраты), только в iSeeYouInCombat добавить создание события:
CODE
procedure iSeeYouInCombat begin
 if combat_is_initialized then begin
  if obj_can_see_obj(self_obj, dude_obj) and свои_условия_для_нападения then attack_setup(self_obj, dude_obj);
  else begin
   addnamedevent("iSeeYouInCombat", iSeeYouInCombat);
   signalnamed("iSeeYouInCombat");
  end
 end
end
Fakeman
Почему в сфале не работает ProcessorIdle  — то что тут устанавливаешь значения ни как не влияет на загрузку проца, она всегда 50% да же в главном меню.
В HRP, если установишь данный фикс то там это работает.

Раньше до твоего фикса, в сфалее вообще нельзя было это включать, ибо скрипты глючили, сейчас вроде нормально.
Crafty
QUOTE (Fakeman)
Почему в сфале не работает ProcessorIdle  — то что тут устанавливаешь значения ни как не влияет на загрузку проца, она всегда 50% да же в главном меню.
В HRP, если установишь данный фикс то там это работает.
QUOTE
;Set a number of milliseconds to idle each input loop in background mode
QUOTE
QUOTE
ProcessorIdle=10
Теперь нормально дружит с опцией HiRes patch CPU_USAGE_FIX=1 или нет?
А раньше не дружил? Просто не было смысла дважды делать одну и ту же работу и использовать совместно. Но по факту никаких побочных проблем не будет.

Оригинальная реализация ProcessorIdle делала идиотскую работу — отдавала тики когда игра была активной, а в фоновом режиме об этом забывала и начинала загружать процессор постоянным опросом клавиатуры. После "! Исправлен функционал переменной ProcessorIdle." всё как и должно быть — в фоновом режиме отдаются тики и загрузка процессора игрой ~0%, а в активном ~50% (с чего бы когда я в игре мне раздавать тики другим процессам).
Fakeman
QUOTE
Исправлен функционал переменной ProcessorIdle." всё как и должно быть — в фоновом режиме отдаются тики и загрузка процессора игрой ~0%, а в активном ~50% (с чего бы когда я в игре мне раздавать тики другим процессам).

В фоновом это когда свернута игра? — не пойму.
В HiRes patch как-то по другому работает — в главном меню практически в 0% в самой игре 50%, а если открыть любой инвентарь то падает до 10%, в общем в HRP эта штука в плане КПД по лучше будет.
Crafty
QUOTE (Fakeman)
В фоновом это когда свернута игра? — не пойму.
Да.
Fakeman
Есть функция tile_is_visible(int tile) — которая в нынешних реалиях c HRP не корректно работает, да и при ванильном разрешении 640х480 она тоже не совсем правильно работает.
Такой вопрос, можно как-то скриптово там подправить код, что-бы она правильно работала?

Или другой вариант, как скриптово получить значение _tile_center_tile
CODE
mov     ebx, ds:_tile_center_tile

функция tile_set_center(tile)
CODE
Макрос от metarule3(METARULE3_TILE_SET_CENTER, tileNum, 0, 0)

корректно работает при смене разрешения, думаю можно было бы от этой кординаты(_tile_center_tile) самим в скрипте узнавать "видим ли гекс на экране".
Crafty
QUOTE (Fakeman)
Есть функция tile_is_visible(int tile) — которая в нынешних реалиях c HRP не корректно работает, да и при ванильном разрешении 640х480 она тоже не совсем правильно работает.
Она сделана для 640x480 (5 гексов) и содержит баг (если прошла проверка по x, то игнорируется по y). Но вообще перевод/описание неправильно понимается ("видим ли гекс на экране") — tile видим если не превышает 5 гексов от tile_center_tile. Ну чтобы float'ы от нпс появлялись только когда ГГ близко.

Сама функция tile_is_visible очень простая:
CODE
x := abs(tile_center_tile - tile) % 200;
y := abs(tile_center_tile - tile) / 200;
if x < 5 then return TRUE;
else if y < 5 then return TRUE;
return FALSE;
Вот картинка, только с 2 гексами (вместо "< 5" использовать "< 2"), а tile_center_tile := 402.

QUOTE (Fakeman)
Или другой вариант, как скриптово получить значение _tile_center_tile
read_int(0x66BE34);
Fakeman
Спасибо.

Как то говорил тебе о возможности метать гранаты на свободный гекс в объект-дверь.
И вот только сейчас решил попробовать такое реализовать, и такой косяк всплыл, в общем нельзя так просто взять и создать "на лету" объект на карте, он тупо не создается, или создается каким-то таким фантомным, и с таким объектом нельзя взаимодействовать.
Только сейчас понял что объекты создаются, только при заходе на карту в map_enter_p_proc, даже если загружаешь игру из сохранки объект не будет создан.
Там какой-то баг в функции create_object_sid или это специально так устроено в движке?
сам указатель на объект создается, но объект не материализован, не появляется на указанных координатах, его можно передвинуть write(obj + 4, tile), но он просто как картинка сверху карты :)

***Хотя я помню что можно было создавать вот так объекты на карте, че за фигня то проблема с map_exit_proc то теперь с create_object_sid, чем больше копаешься тем больше говна всплывает из движка, кривой движок как моя жизнь))

Может такую фишку можно сделать на уровне движка, или это технически не возможно?
Crafty
QUOTE (Fakeman)
или создается каким-то таким фантомным, и с таким объектом нельзя взаимодействовать.
set_obj_visibility :-p

QUOTE (Fakeman)
его можно передвинуть write(obj + 4, tile)
move_to ;)
Fakeman
Ну блин кривой движок) Попробовал еще раз, во так работает
CODE
targetObject := create_object_sid(33554434, hex_cursor, 0, -1);
write_int(targetObject + 0x4, hex_cursor); // аля move_to

если конкретно указывать уровень карты нулевой, а если в параметр уровня вписать tile_num(dude_obj) то ни хрена, глючит игру, хотя игрок также на 0 уровне.

***ахах вот я тупанул))) вписал в элеватор, гекс игрока tile_num(dude_obj) — что-то заработался я сегодня...

QUOTE
Жертвы разбегаются после получения дамага от взрыва в дверь и не нападают. Можно и нужно выйти из боя, чтобы напали.

Ага, твари не нападают можно что-то сделать) или пролет как фанера над парижем?
Давай под напряги извилинки, сделаешь будет новая фишка в метании гранат.

И еще как узнать какой текущий режим атаки выбран у оружия в руках.
Т.е. вот эти вот значения режима интересует
CODE
#define ATTACK_MODE_NONE        0
#define ATKMODE_PRI_PUNCH       1
#define ATKMODE_PRI_KICK        2
#define ATKMODE_PRI_SWING       3
#define ATKMODE_PRI_THRUST      4
#define ATKMODE_PRI_THROW       5
#define ATKMODE_PRI_SINGLE      6
#define ATKMODE_PRI_BURST       7
#define ATKMODE_PRI_FLAME       8
#define ATKMODE_SEC_PUNCH      16  // 0x00000010
#define ATKMODE_SEC_KICK       32  // 0x00000020
#define ATKMODE_SEC_SWING      48  // 0x00000030
#define ATKMODE_SEC_THRUST     64  // 0x00000040
#define ATKMODE_SEC_THROW      80  // 0x00000050
#define ATKMODE_SEC_SINGLE     96  // 0x00000060
#define ATKMODE_SEC_BURST     112  // 0x00000070
#define ATKMODE_SEC_FLAME     128  // 0x00000080
Crafty
QUOTE (Fakeman)
write_int(targetObject + 0x4, hex_cursor); // аля move_to
Лучше всё же move_to, посколько он делает дополнительные необходимые штуки вроде выравнивания уровня света.

QUOTE (Fakeman)
Ага, твари не нападают можно что-то сделать) или пролет как фанера над парижем?
Давай под напряги извилинки, сделаешь будет новая фишка в метании гранат.
Это я уже ничё не помню...

QUOTE (Fakeman)
И еще как узнать какой текущий режим атаки выбран у оружия в руках.
Вообще в бою get_attack_type возвращает ATKTYPE_*.
QUOTE (Fakeman)
Т.е. вот эти вот значения режима интересует
Это битовые значения для определения субтипа оружия в прошниках, можно прочитать get_proto_data(weapon_pid, 0x18) и bwand.
Fakeman
QUOTE
Лучше всё же move_to

да, я так увлекся всякими read/write что забыл что есть move

QUOTE
Вообще в бою get_attack_type возвращает ATKTYPE_*.

Так это другое, и там некоторых режимов нет.
и вообще он какой-то не понятный что значат эти WEP1/2
CODE
#define ATKTYPE_LWEP1           (0)
#define ATKTYPE_LWEP2           (1)
#define ATKTYPE_RWEP1           (2)
#define ATKTYPE_RWEP2           (3)

*** а кажись начинаю догонять — видимо это режим в котором находится оружие — те Primary/Secondary Mode надо будет проверить.

QUOTE
Это битовые значения для определения субтипа оружия в прошниках, можно прочитать get_proto_data(weapon_pid, 0x18) и bwand.

Да не из прошек надо, а из текущего типа атаки установленного у оружия.
Вот есть у оружия два типа SINGLE и BURST как ты узнаешь в каком режиме сейчас оружие. И нужно узнавать до совершения атаки.

QUOTE
Это я уже ничё не помню...

Ну надо вспомнить)
Покажи хоть что ты там на исправлял для дверей.
Crafty
QUOTE (Fakeman)
и вообще он какой-то не понятный что значат эти WEP1/2
А так:
CODE
hit_left_weapon_primary    = 0
hit_left_weapon_secondary  = 1
hit_right_weapon_primary   = 2
hit_right_weapon_secondary = 3

QUOTE (Fakeman)
Вот есть у оружия два типа SINGLE и BURST как ты узнаешь в каком режиме сейчас оружие.
Если гиморно, то чтение из прошника оружия поля flags_ext и разбор в зависимости от основной/дополнительной атаки. Или использование движковых функций/данных напрямую.
Лучше опиши реальный пример практического использования, от этого и будем плясать.

QUOTE (Fakeman)
Покажи хоть что ты там на исправлял для дверей.
Ничё не помню :(
Fakeman
QUOTE
Лучше опиши реальный пример практического использования, от этого и будем плясать.

Ну вот для этого случая и надо, когда в руке установлена оружие в режим метания.
сейчас для этого используется неправильный способ:
CODE
dmg_type := get_proto_data(pid, PROTO_WP_DMG_TYPE);
attack_mode := get_proto_data(pid, PROTO_IT_FLAGS);
if (dmg_type == DMG_explosion or dmg_type == DMG_fire)
  and ((attack_mode bwand ATKMODE_PRI_THROW) or (attack_mode bwand ATKMODE_SEC_THROW)
   or (attack_mode bwand ATKMODE_PRI_THROW + ATKMODE_SEC_THROW)) then begin

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

+ подскажи где задаются координаты для отладочного окна, оно появляется чуть ли не посредине экрана) я забадался уже его постоянно сдвигать в сторону.
Crafty
QUOTE (Fakeman)
Ну вот для этого случая и надо, когда в руке установлена оружие в режим метания.
hs_keypress.ssl:
CODE
procedure start;

procedure start begin
 if not init_hook then begin
  variable event := get_sfall_arg, keyDX := get_sfall_arg, keyVK := get_sfall_arg;
  if (keyDX == 0x57) and (event == 0) then begin // F11
   variable hand_data, mode, attack_anim, isSecondary := "";
   hand_data := active_hand * 24 + 0x5970F8;
   mode := read_int(hand_data+16);
   if mode == 2 or mode == 4 then isSecondary := "прицельно ";
   if mode == 1 or mode == 2 then mode := read_int(hand_data+8);
   else if mode == 3 or mode == 4 then mode := read_int(hand_data+12);
   if mode == 5 then display_msg("перезарядка");
   else begin
    attack_anim := call_offset_r2(0x4785DC, dude_obj, mode);
    if attack_anim == 16 then display_msg(isSecondary+"удар рукой");
    else if attack_anim == 17 then display_msg(isSecondary+"удар ногой");
    else if attack_anim == 42 then display_msg(isSecondary+"рубить");
    else if attack_anim == 41 then display_msg(isSecondary+"ткнуть");
    else if attack_anim == 18 then display_msg(isSecondary+"метнуть");
    else if attack_anim == 45 then display_msg(isSecondary+"выстрел");
    else if attack_anim == 46 then display_msg(isSecondary+"очередь");
    else if attack_anim == 47 then display_msg(isSecondary+"огонь");
   end
  end
 end
end

QUOTE (Fakeman)
Ну блин покопайся там в исходниках узнай почему сразу не атакуют, может гдето надо что-то предварительно установить.
Нет смысла сейчас :-p

QUOTE (Fakeman)
+ подскажи где задаются координаты для отладочного окна, оно появляется чуть ли не посредине экрана) я забадался уже его постоянно сдвигать в сторону.
0xCC74D или 0x4DC34D, там 80, и для x и y.
Fakeman
Там по проще функция рядом есть, указываешь указатель на предмет, вместо игрока.
CODE
item_w_anim_weap_

А что за mode требуется? что-то с ним какие-то сложные расчеты, в чем его смысл?

QUOTE
Нет смысла сейчас :-p

Что значит нет смысла?
Crafty
QUOTE (Fakeman)
Там по проще функция рядом есть, указываешь указатель на предмет, вместо игрока.
Ну ты не уточнял что для конкретного предмета, поэтому я использовал более универсальную.

QUOTE (Fakeman)
А что за mode требуется? что-то с ним какие-то сложные расчеты, в чем его смысл?
Это режим ATKTYPE_*, функция get_attack_type нормально сработает только в очень комфортных условиях. В общем я сейчас её подправил и можно кусок кода (но без прицельности) в предыдущем примере переписать так:
CODE
variable mode, attack_anim;
mode := get_attack_type;
if mode == 6 or mode == 7 then display_msg("перезарядка");
else begin
 attack_anim := call_offset_r2(0x4785DC, dude_obj, mode);
 if attack_anim == 16 then display_msg("удар рукой");
 else if attack_anim == 17 then display_msg("удар ногой");
 else if attack_anim == 42 then display_msg("рубить");
 else if attack_anim == 41 then display_msg("ткнуть");
 else if attack_anim == 18 then display_msg("метнуть");
 else if attack_anim == 45 then display_msg("выстрел");
 else if attack_anim == 46 then display_msg("очередь");
 else if attack_anim == 47 then display_msg("огонь");
end

QUOTE (Fakeman)
Что значит нет смысла?
Так проект закрыт :-p
Fakeman
QUOTE
Так проект закрыт :-p

Не может быть!

А в чем отличие между когда атакуешь объект Scenery и Critter ?
Вот ты меня вынуждаешь вместо двери создавать объект Critter, хотя дверь правильнее, там проценты серенькие, и нету сообщений что объект перенес атаку без последствий.

Отправлено: 1 дек 17 04:05
Я тут побаловаться этой штукой с дверью и гранатой, как оказываться в дверь то легче попасть чем в непеся, видимо модификатор брони(AC) влияет на % попадания да? — я что-то это как-то не учел, читерно как-то это получается метать гранаты на соседний гекс от непеся, зато реалистично кидай куда хочешь, как во всех тактик играх.

Давай расчехляй свой проект :P
Надо дофиксить опцию ExplosionAroundPortal
*Хотя может я скриптово добью это дело через хук какой-нибудь, потому как если в damage_p_proc нпс добавить attack(source_obj) то нпс сразу будет атаковать.
Fakeman
CODE

0045270A            call    gsound_play_sfx_file_
0045270F            cmp     eax, 0FFFFFFFFh
00452712            jz      short loc_45271F
00452714            mov     ecx, [esp+14h+var_14]
00452717            push    ecx
00452718            push    offset aGsoundPlayingA  ; "\nGsound: playing ambient map sfx: %s"
0045271D            jmp     short loc_452728
---------------------------------------------------------------------------
0045271F loc_45271F:                                ; gsound_sfx_q_process_+DEj
0045271F            mov     edx, [esp+14h+var_14]
00452722            push    edx
00452723            push    offset aGsoundPlayin_0  ; "\nGsound: playing ambient map sfx: %s. "...
00452728 loc_452728:                                ; gsound_sfx_q_process_+E9j
00452728            call    debug_printf_
0045272D            add     esp, 8

Отключил ненужную информацию в логе о "Gsound: playing ambient map sfx: %s"
и перепрыгиваю с jmp short loc_452728 за debug_printf_, тут нужно прыгать на add esp, 8 или add esp тоже надо пропускать? — пока прыгаю на нее но вдруг это неправильно.

У тебя там в опкодах добавлено, это ты свое добавлял(хотя навряд ли) — просто забыли что он есть?
CODE
0x824A - void block_combat(bool flag)

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

Еще как-то спрашивал но ты не ответил, у тебя в hs_withinperception.ssl используется sneak_success но раньше у тебя там была движковая функция, ты как-то подправил у себя sneak_success? — ибо ты раньше говорил что оригинальная с косяком.

Ты все такие не документированные правки куда-нибудь в отдельный файлик пиши, чтобы знать.
и get_attack_type тоже укажи, что работает теперь по другому (правильно).
Crafty
QUOTE (Fakeman)
А в чем отличие между когда атакуешь объект Scenery и Critter ?
Тю, а то я так и знаю/помню — смотреть надо :-p
QUOTE (Fakeman)
видимо модификатор брони(AC) влияет на % попадания да?
Да.
QUOTE (Fakeman)
Давай расчехляй свой проект :P
Надо дофиксить опцию ExplosionAroundPortal
Нет смысла сейчас ;)
QUOTE (Fakeman)
тут нужно прыгать на add esp, 8 или add esp тоже надо пропускать?
Второе.
QUOTE (Fakeman)
что опкод делает — не дает войти в режим боя?
Блокирует вхождение в бой с помощью клавиши или иконки оружия на интерфейсной панели. И почему забыли?
QUOTE (Fakeman)
ты как-то подправил у себя sneak_success? — ибо ты раньше говорил что оригинальная с косяком.
Давно ещё, hs_keypress.ssl:
CODE
procedure start;
procedure start begin
 if not init_hook then begin
  variable event := get_sfall_arg, keyDX := get_sfall_arg, keyVK := get_sfall_arg;
  if (keyDX == 0x57) and (event == 0) then begin // F11
   critter_mod_skill(dude_obj, 8, 300);
   if sneak_success then display_msg("success"); else display_msg("failed");
  end
 end
end
Нажми F11, 1, F11, 1, F11.
Fakeman
CODE
Нет смысла сейчас;)

Ладно. тут похоже надо ситуацию скриптово поправлять.

Как узнать, может ли игрок в текущий момент выйти из боя — это когда пишет "вы не можете закончить бой рядом с врагами", т.е как определяется что есть враги?
я полагаю где-то у криттера есть флаг означающий, что он является врагом для dude?

QUOTE
Давно ещё

Поделись исправлением, чтоб в ориге исправить.

QUOTE
И почему забыли?

Ну потому, что не вписали. :)
Crafty
QUOTE (Fakeman)
Как узнать, может ли игрок в текущий момент выйти из боя — это когда пишет "вы не можете закончить бой рядом с врагами", т.е как определяется что есть враги?
Для всех персонажей на карте нужно вызвать combatai_want_to_stop и combatai_want_to_join, в общем смотри как это сделано в combat_end.

QUOTE (Fakeman)
Поделись исправлением, чтоб в ориге исправить.
Есть в сишных исходниках.
Ваш ответ: