Fakeman
12 November 2017 | 14:53
Ок, гляну в чем там у меня проблема. Помню что вроде как работало, а вчера тык-мык уже не работает.
Отправлено: 12 ноя 17 16:59
В общем это не у меня проблема, а в движке, я не знаю как ты там тесты проводишь, что у тебя ничего не получается с ними) то мобы у тебя тоже почему то сами себя не бьют.
В общем рассказываю как надо правильно делать тесты, берешь чистый фол без всяких сфалов меняешь скрипт DUDEку, тупо можно без логики с процедурой map_exit_p_proc с простым display_msg("map_exit_p_proc");
Начинаешь новую игру и смотришь, что при заходе в храм, не срабатывает обработчик выхода из карты.
Далее новая игра сохраняемся-загружаемся, входим в храм обработчик срабатывает но только 1 раз пока не сделаем загрузку игры.
Crafty
13 November 2017 | 01:52
QUOTE (Fakeman) |
Начинаешь новую игру и смотришь, что при заходе в храм, не срабатывает обработчик выхода из карты. Далее новая игра сохраняемся-загружаемся, входим в храм обработчик срабатывает но только 1 раз пока не сделаем загрузку игры. |
Да, это увидел сразу (для моего теста выход/возврат из/в пещер[ы]), но map_exit_p_proc всё равно будет срабатывать позже (в том же Кламате для моего теста, то есть не будет ситуации "последующие выходы в текущей сессии игры не вызывают данный обработчик.", а то я сначала решил что вообще перестанет срабатывать).
С некоторыми картами (или ситуациями) действительно фигня убирается скрипт ГГ из списка скриптов персонажей до вызова map_exit_p_proc (для стартовой можно в acklint добавить сообщение и увидеть что для него срабатывает всегда при заходе в храм).
Смирись, kek ;)
Fakeman
13 November 2017 | 16:19
QUOTE |
но map_exit_p_proc всё равно будет срабатывать позже (в том же Кламате для моего теста |
А от чего это будет зависить, что позже сработает?
может эту особеность поведения можно где-нибудь применить.
Crafty
16 November 2017 | 01:17
QUOTE (Fakeman) |
А от чего это будет зависить, что позже сработает? может эту особеность поведения можно где-нибудь применить. |
Баг это, а не особенность :-p
Fakeman
16 November 2017 | 16:06
Еще такой вопрос меняю пид в движке для сенсора на 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
16 November 2017 | 17:04
QUOTE (Fakeman) |
Еще такой вопрос меняю пид в движке для сенсора на ACTIVE_MOTION_SENSOR (208) а игра почему-то говорит что в руке не установлен сенсор, т.е. вообще перестает работать и для пида MOTION_SENSOR |
Так в руке у тебя всё так же остаётся сенсор с PID_MOTION_SENSOR. Движок не использует PID_ACTIVE_MOTION_SENSOR.
QUOTE (Fakeman) |
Там почему-то 1 байт отводится под пид и что-то у меня такое впечатление что число 208 он считает отрицательным, такое вообще бывает в ассеблере? |
Бывает, но не в этом случае там нет знаковой проверки.
QUOTE (Fakeman) |
Или где-то еще есть и оно не указанно. |
Какая-то адская задумка... :-p
Fakeman
16 November 2017 | 17:12
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
16 November 2017 | 17:38
QUOTE (Fakeman) |
Чуешь разницу) |
2 байта :-p
Но [не]знаковость определяется следующей (как правило) командой (или командами) jb != jl.
Fakeman
16 November 2017 | 19:20
Я тебе не тот код нарисовал, но суть не поменялась, один байт под пид, когда нужно 2 минимум.
Дальше там jz проверка перехода нет, значит сравниваемые операнды не равны.
С пид меньше 128 все отлично.
Видимо компилятор не тот машинный код с генерировал для движка.
Узнай как работает этот машинный код, 3В это пид.
это все тот же cmp eax+iobj.pid, PID_ но у них разный машинный код.
Crafty
17 November 2017 | 00:00
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
17 November 2017 | 01:10
QUOTE |
это команда CMP. Она сравнивает операнды и изменяет регистр флагов. |
А где в вашей табличке флаг ZF ? она его меняет(уст. в 1) если результат сравнения равен 0, т.е. если операнды равны.
Crafty
17 November 2017 | 01:27
QUOTE (Fakeman) |
А где в вашей табличке флаг ZF ? она его меняет(уст. в 1) если результат сравнения равен 0, т.е. если операнды равны. |
Всю таблицу нужно было скопировать? Добавил :-p
Fakeman
17 November 2017 | 02:25
Добавил молодец)
Теперь разбирайся почему не устанавливается флаг ZERO если второй операнд больше 127 :)
CODE |
cmp [eax+iobj.pid], PID_ACTIVE_MOTION_SENSOR jz short loc_41BC17 |
Crafty
17 November 2017 | 03:30
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
17 November 2017 | 05:02
В сфале стоит дефолтное для движка поведение.
Если я записываю другой пид write_byte(0x41BBFC, 100) то этот предмет становится как датчик.
Да тут явно проц считает что ему дают отрицательное число для сравнения, поэтому в операции сравнения не уст флаг zero. Не зря же там разные машинные коды.
Crafty
17 November 2017 | 05:49
QUOTE (Fakeman) |
Не зря же там разные машинные коды. |
Как скажешь ;)
Fakeman
17 November 2017 | 16:20
Смотри из движка.
CODE |
00411231 cmp eax, 0FFFFFFFEh нех opcode: 83 F8 FE |
это же число -2, а не 4294967294, хотя это так-же можно считать числом 254.
В общем везде где нужно сравнить число больше 7F в исходниках используется не одно байтовый второй операнд.
Crafty
17 November 2017 | 17:34
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
17 November 2017 | 19:06
Я же написал пример, логика скрипта вообще тут не важна.
CODE |
write_byte(0x41BBFC, PID_ACTIVE_MOTION_SENSOR); write_byte(0x41BC12, PID_ACTIVE_MOTION_SENSOR);
|
Подставляем любой пид больше 127, ложим этот предмет в руку открываем карту и нажимаем кнопку "сканер", игра будет думать что указанного предмета в руке нет.
Заменим на любой пид меньше 128 и пробуем, все работает.
Короче забей.
Crafty
17 November 2017 | 22:15
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
18 November 2017 | 01:39
Такс у меня новая проблема.
Когда используешь какой-либо предмет (пиктограмма руки) из открытого инвентаря игрока, то этот предмет нельзя удалить, что-то блокирует по видимому его в движке, 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
18 November 2017 | 03:05
QUOTE (Fakeman) |
В общем какие скриптовые манипуляции нужно сделать что-бы двиг корректно удалил предмет, как он это делает в случае когда когда используешь аптечки. |
rm_obj_from_inven(source, item) перед destroy_object(item), не?
Fakeman
18 November 2017 | 04:56
Нет) тоже самое будет, если использовать другую функцию которая удаляет несколько экземпляров то она возвратит 0. Что-то в движке не дает удалить этот предмет.
Я уже напрямую использовал двиг.функцию _destroy_obj и без результата.
Crafty
18 November 2017 | 06:55
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
18 November 2017 | 10:55
Я и так сохраняю указатель из хука при использовании, потом этот указатель в useskill использую, но проблема то в том что ноок использования отрабатывает до ноока скила.
Ладно я кажись понял как его удалить, те получается нужно удалять после отработки useskill.
Fakeman
19 November 2017 | 01:17
Вот новый косяк, при использовании предмета через контекстное меню рюкзака(пиктограмма), если таковых предметов в стопке имеется несколько штук, то эти все предметы(в стопке) имеют один указатель, и при уменьшении у предмета в стопе заряда, заряды уменьшается сразу у всех предметов в стопки (помнится ты об этом говорил, когда речь шла об износе предметов).
В общем как узнать сколько лежит предметов в такой стопке?
Или может есть какой-то механизм отделения их друг от друга)
Fakeman
19 November 2017 | 17:59
проблема решена, уже есть такая функция
QUOTE |
В общем как узнать сколько лежит предметов в такой стопке? |
obj_is_carrying_obj
Fakeman
25 November 2017 | 01:18
CODE |
addnamedhandler("iSeeYouInCombat", iSeeYouInCombat); // не addnamedevent! |
О перечитывал тему и увидел такое, а в чем отличие AddNamedHandler от AddNamedEvent ?
Crafty
25 November 2017 | 15:04
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
25 November 2017 | 16:42
Почему в сфале не работает ProcessorIdle то что тут устанавливаешь значения ни как не влияет на загрузку проца, она всегда 50% да же в главном меню.
В HRP, если установишь данный фикс то там это работает.
Раньше до твоего фикса, в сфалее вообще нельзя было это включать, ибо скрипты глючили, сейчас вроде нормально.
Crafty
25 November 2017 | 17:33
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
25 November 2017 | 21:23
QUOTE |
Исправлен функционал переменной ProcessorIdle." всё как и должно быть в фоновом режиме отдаются тики и загрузка процессора игрой ~0%, а в активном ~50% (с чего бы когда я в игре мне раздавать тики другим процессам). |
В фоновом это когда свернута игра? не пойму.
В HiRes patch как-то по другому работает в главном меню практически в 0% в самой игре 50%, а если открыть любой инвентарь то падает до 10%, в общем в HRP эта штука в плане КПД по лучше будет.
Crafty
28 November 2017 | 15:15
QUOTE (Fakeman) |
В фоновом это когда свернута игра? не пойму. |
Да.
Fakeman
28 November 2017 | 18:40
Есть функция 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
28 November 2017 | 19:45
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
29 November 2017 | 23:50
Спасибо.
Как то говорил тебе о возможности метать гранаты на свободный гекс в объект-дверь.
И вот только сейчас решил попробовать такое реализовать, и такой косяк всплыл, в общем нельзя так просто взять и создать "на лету" объект на карте, он тупо не создается, или создается каким-то таким фантомным, и с таким объектом нельзя взаимодействовать.
Только сейчас понял что объекты создаются, только при заходе на карту в map_enter_p_proc, даже если загружаешь игру из сохранки объект не будет создан.
Там какой-то баг в функции create_object_sid или это специально так устроено в движке?
сам указатель на объект создается, но объект не материализован, не появляется на указанных координатах, его можно передвинуть write(obj + 4, tile), но он просто как картинка сверху карты :)
***Хотя я помню что можно было создавать вот так объекты на карте, че за фигня то проблема с map_exit_proc то теперь с create_object_sid, чем больше копаешься тем больше говна всплывает из движка, кривой движок как моя жизнь))
Может такую фишку можно сделать на уровне движка, или это технически не возможно?
Crafty
30 November 2017 | 00:42
QUOTE (Fakeman) |
или создается каким-то таким фантомным, и с таким объектом нельзя взаимодействовать. |
set_obj_visibility :-p
QUOTE (Fakeman) |
его можно передвинуть write(obj + 4, tile) |
move_to ;)
Fakeman
30 November 2017 | 01:15
Ну блин кривой движок) Попробовал еще раз, во так работает
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
30 November 2017 | 03:44
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
30 November 2017 | 04:43
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
30 November 2017 | 15:50
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
30 November 2017 | 16:08
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
30 November 2017 | 20:22
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
30 November 2017 | 22:37
Там по проще функция рядом есть, указываешь указатель на предмет, вместо игрока.
А что за mode требуется? что-то с ним какие-то сложные расчеты, в чем его смысл?
QUOTE |
Нет смысла сейчас :-p |
Что значит нет смысла?
Crafty
30 November 2017 | 23:25
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
1 December 2017 | 00:12
QUOTE |
Так проект закрыт :-p |
Не может быть!
А в чем отличие между когда атакуешь объект Scenery и Critter ?
Вот ты меня вынуждаешь вместо двери создавать объект Critter, хотя дверь правильнее, там проценты серенькие, и нету сообщений что объект перенес атаку без последствий.
Отправлено: 1 дек 17 04:05
Я тут побаловаться этой штукой с дверью и гранатой, как оказываться в дверь то легче попасть чем в непеся, видимо модификатор брони(AC) влияет на % попадания да? я что-то это как-то не учел, читерно как-то это получается метать гранаты на соседний гекс от непеся, зато реалистично кидай куда хочешь, как во всех тактик играх.
Давай расчехляй свой проект :P
Надо дофиксить опцию ExplosionAroundPortal
*Хотя может я скриптово добью это дело через хук какой-нибудь, потому как если в damage_p_proc нпс добавить attack(source_obj) то нпс сразу будет атаковать.
Fakeman
1 December 2017 | 17:28
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
3 December 2017 | 05:03
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
3 December 2017 | 18:05
Ладно. тут похоже надо ситуацию скриптово поправлять.
Как узнать, может ли игрок в текущий момент выйти из боя это когда пишет "вы не можете закончить бой рядом с врагами", т.е как определяется что есть враги?
я полагаю где-то у криттера есть флаг означающий, что он является врагом для dude?
Поделись исправлением, чтоб в ориге исправить.
Ну потому, что не вписали. :)
Crafty
3 December 2017 | 18:27
QUOTE (Fakeman) |
Как узнать, может ли игрок в текущий момент выйти из боя это когда пишет "вы не можете закончить бой рядом с врагами", т.е как определяется что есть враги? |
Для всех персонажей на карте нужно вызвать combatai_want_to_stop и combatai_want_to_join, в общем смотри как это сделано в combat_end.
QUOTE (Fakeman) |
Поделись исправлением, чтоб в ориге исправить. |
Есть в сишных исходниках.