You are not logged in.
хех, я кстати решаю эту проблему уже давно (правда с другой целью), и вот вчера и сегодня я её почти решил))) если всё пойдёт норм, то выложу код сюда...(первые тесты показывают что всё раб...)
кстати, тебе для клео или для майна?))просто если делать для клео, то немного некрасивый поворот получается (рывками, правда не слишком заметными...)
Last edited by BoPoH (24-10-2010 11:31)
Offline
тебе, тебе, кому же ещё!) ну раз для майна, то....мне как раз тоже для майна...блин я тут кучу потоков понаделал, не знаю зачем...щас упрощу как можно сильнее и выложу)
------------------------------------------------------------------------------------------
так, это первая версия, сидел, вспоминал систему координат по математике, и вот вроде получилось кое-что... незнаю, может быть можно как-то упростить это, применить другую формулу вычисления (синусы, косинусы какие-нибудь=)), d88, тебе если следить за актёром - должно быть без рывков, а вот если какие-то резкие движения будут, там уже надо будет создавать метки LOOK (начиная с if and), LOOK_1, LOOK_2 и LOOK_3 как отдельные потоки, а то слишком долго с одной метки на другую переходит... вот собственно сам код:
var 4@ : Float 5@ : Float 10@ : Float 11@ : Float end :LOOK wait 0 if // тут какая-нибудь проверка, например, не дошёл ли актёр куда надо... jf @LOOK actor.StorePos($ХЭНДЛ_АКТЁРА_ЗА_КОТОРЫМ_СЛЕДЯТ 4@, 5@, 6@) actor.StorePos($PLAYER_ACTOR, 10@, 11@, 12@) 4@ -= 10@ 5@ -= 11@ 8@ = 90.0 0087: 9@ = 4@ // 9@ = X 0087: 13@ = 5@ // 13@ = Y if and 9@ > 0.0 13@ > 0.0 jf @LOOK_1 005B: 4@ += 5@ // X + Y 0073: 8@ /= 4@ // 90.0 / (X + Y) 006B: 8@ *= 9@ // 8@ * X 8@ *= -1.0 jump @LOOK_FINAL :LOOK_1 wait 0 if and 9@ > 0.0 13@ < 0.0 jf @LOOK_2 4@ *= -1.0 005B: 4@ += 5@ // X + Y 0073: 8@ /= 4@ // 90.0 / (X + Y) 006B: 8@ *= 9@ // 8@ * X 8@ += 180.0 8@ *= -1.0 jump @LOOK_FINAL :LOOK_2 wait 0 if and 9@ < 0.0 13@ < 0.0 jf @LOOK_3 4@ *= -1.0 5@ *= -1.0 005B: 4@ += 5@ // X + Y 0073: 8@ /= 4@ // 90.0 / (X + Y) 006B: 8@ *= 9@ // 8@ * X 8@ += 180.0 jump @LOOK_FINAL :LOOK_3 wait 0 if and 9@ < 0.0 13@ > 0.0 jf @LOOK 5@ *= -1.0 005B: 4@ += 5@ // X + Y 0073: 8@ /= 4@ // 90.0 / (X + Y) 006B: 8@ *= 9@ // 8@ * X :LOOK_FINAL actor.Angle($PLAYER_ACTOR) = 8@ jump @LOOK
так сходу алгоритм сего не понять, если надо будет, я могу объяснить...
вариант с майном (несколько потоков) пока не доработал...
Last edited by BoPoH (24-10-2010 13:36)
Offline
А почему при использовании 0ABF: set_vehicle 0@ engine_state_to 0/1 машина становится не восприимчивой к урону? Можно это как то пофиксить?
Offline
Offline
хаха, не знал...может стоит попробовать убрать иммунитеты - Car.SetImmunities($CAR, 0, 0, 0, 0, 0)
А не помогает. Пытался выключать и включать двигатель другими опкодами, так там выключить то получается, а включить нет. А мне всего-то надо удерживать машину на месте 2500 ms, чтоб она не начинала ехать мгновенно.
Last edited by Sergey81 (24-10-2010 15:43)
Offline
Offline
дык воспользуйся Car.LockInCurrentPosition($car) = True
Хм, не знал о таком, спасибо, подходит.
Offline
LOOK_1, LOOK_2 и LOOK_3 как отдельные потоки, а то слишком долго с одной метки на другую переходит
Много раз уже это обсуждалось - не надо ставить wait после каждой метки. В идеале должен быть один wait на весь скрипт, т.к. каждый wait приостанавливает работу скрипта на десятки мс.
Offline
да я уже давно заметил что wait сильно замедляет скрипт, но дело в том что часто, если забывал где-то поставить wait, зависало, а где-то тут на форуме прочитал что нужно ставить wait перед проверкой...хотя я решил попробовать без wait'ов, и сейчас не зависало...может объяснишь, когда нужно ставить wait, а когда не надо? Предполагаю что ставить надо тогда, когда в jump_if_false пишешь имя той же метки,...я прав?
Last edited by BoPoH (25-10-2010 13:13)
Offline
да я уже давно заметил что wait сильно замедляет скрипт, но дело в том что часто, если забывал где-то поставить wait, зависало, а где-то тут на форуме прочитал что нужно ставить wait перед проверкой...
Не перед каждой проверкой, а если она в цикле. Короче в циклах нужен хотя бы один вайт, даже он нулевой.
Кстати, ты ещё не закончил тестировать свой код?
Offline
дык можешь использовать тот что я дал, только убери wait'ы, и всё должно работать, к тому же, я сегодня спрашивал у училки по математике, она сказала что там что-то связано с косинусами и синусами, однако сегодня у неё не было кое-какой таблицы, поэтому, алгоритм, как сразу узнать (без всяких проверок) нужный угол я узнаю завтра...кстати может быть знаете, как узнать угол, зная его синус и косинус...ну и тангенс...
Offline
может объяснишь, когда нужно ставить wait, а когда не надо?
Если скрипт в течение длительного времени не будет передавать управление игре (а это происходит благодаря команде wait), то игра зависнет. Поэтому wait необходим в бесконечных циклах, циклах с проверкой на загрузку модели, при последовательном запуске нескольких scm-функций (т.к. они довольно ресурсоёмкие).
Можешь ещё прочитать сказку от listener: http://sannybuilder.com/forums/viewtopi … 667#p12667
кстати может быть знаете, как узнать угол, зная его синус и косинус...ну и тангенс...
Тут есть три возможности:
1.Воспользоваться опкодом
0604: get_Z_angle_for_point 0@ 1@ store_to 2@
В немодифицированной игре он использовался для нахождения угла между отрезком, лежащим в горизонтальной плоскости, и направлением на север. Если в 0@ записать разницу x-координат (x-координата конца отрезка - x-координата начала отрезка), а в 1@ - разницу y-координат (y-координата конца отрезка - y-координата начала отрезка), то угол будет записан в 2@.
Этот опкод можно применить и для вычисления угла между отрезком и горизонтальной поверхностью (угол будет получен в пределах 0-90 градусов). В 0@ нужно записать разницу z-координат (z-координата начала отрезка - z-координата конца отрезка), а в 1@ - расстояние между проекциями точек начала и конца отрезка на горизонтальную плоскость (воспользоваться опкодом 0509).
2.Воспользоваться дополнительными опкодами arcsin, arccos, arctan от Sanchez
3.Разложить синус, косинус или тангенс в ряд.
Last edited by Den_spb (25-10-2010 17:40)
Offline
Тут есть три возможности:
1.Воспользоваться опкодом0604: get_Z_angle_for_point 0@ 1@ store_to 2@В немодифицированной игре он использовался для нахождения угла между отрезком, лежащим в горизонтальной плоскости, и направлением на север. Если в 0@ записать разницу x-координат (x-координата конца отрезка - x-координата начала отрезка), а в 1@ - разницу y-координат (y-координата конца отрезка - y-координата начала отрезка), то угол будет записан в 2@.
Этот опкод можно применить и для вычисления угла между отрезком и горизонтальной поверхностью (угол будет получен в пределах 0-90 градусов). В 0@ нужно записать разницу z-координат (z-координата начала отрезка - z-координата конца отрезка), а в 1@ - расстояние между проекциями точек начала и конца отрезка на горизонтальную плоскость (воспользоваться опкодом 0509).
2.Воспользоваться дополнительными опкодами arcsin, arccos, arctan от Sanchez
3.Разложить синус, косинус или тангенс в ряд.
тут я конечно половину сказанного не понял))ну да ладно...всё дело в том что мне нужна формула (алгоритм), по которой я бы мог вычислить угол образованный осью Y игрока и отрезком (наверное правильней сказать лучом) проведённым из координат игрока до координат которые я задаю сам...короче говоря - вот нарисовал картинку)) кстати, насчёт того что у тебя написано: в пределах 0-90 градусов - это я уже сумел сделать теми вычислениями, код которых я дал раньше...мне нужна такая формула (алгоритм), с помощью которой можно было вычислить угол в пределах 0-360 градусов, тоесть чтобы можно было вычислить, даже если X и/или Y отрицательны (смотрим картинку, хотя там они положительны..)
Last edited by BoPoH (25-10-2010 18:48)
Offline
Offline
Offline
Не подскажете, как узнать адрес функции загруженой из *.asi?
Offline
Не подскажете, как узнать адрес функции загруженой из *.asi?
0AA4: 0@ = get_proc_address "GetVersion" library 1@ // IF and SET
имя функции регистрозависимое, поэтому в опциях SB нужно поставить галочку "как есть" в форматировании строк.
Offline
Sanchez, не понял зачем там где ты вычисляешь c (по идее по теореме пифагра) ты добавил -2abcosC, хотя это мне уже не нужно...
Den_spb, насчёт этого опкода:
0604: get_Z_angle_for_point 0@ 1@ store_to 2@
ты сказал:
угол будет получен в пределах 0-90 градусов
поэтому я не стал его проверять, но сейчас всё же решил проверить и как оказалось он работает на все 360 градусов, короче говоря, это то что мне было нужно)) спасибо большое, очень выручил!)
d88, вот код скрипта который тебе нужен:
:LOOK wait 0 if // тут какая-нибудь проверка, например, не дошёл ли актёр куда надо... jf @LOOK actor.StorePos($ХЭНДЛ_АКТЁРА_ЗА_КОТОРЫМ_СЛЕДЯТ 1@, 2@, 3@) actor.StorePos($PLAYER_ACTOR, 4@, 5@, 6@) 0063: 1@ -= 4@ // (float) 0063: 2@ -= 5@ // (float) 0604: get_Z_angle_for_point 1@ 2@ store_to 7@ actor.Angle($PLAYER_ACTOR) = 7@ jump @LOOK
правда, я не заметил разницы в скорости работы скриптов, как можно избавиться от wait в этом скрипте?
у меня проверка такого вида:
:LOOK wait 0 if or actor.Animation($PLAYER_ACTOR) == "FALL_COLLAPSE" actor.Animation($PLAYER_ACTOR) == "ROLL" jf @LOOK
и ещё, объясните пожалуйста, как правильно пользоваться while...end
Last edited by BoPoH (26-10-2010 15:19)
Offline
@Seemann - Спасибо. Не можешь ответить ещё на один вопрос про ASI?
ASI в отличие от обычной DLL загружается в память автоматически при старте игры. Тогда как получить её хэндл? Загрузить ещё раз опкодом 0AA2 или как?
Offline
Есть одна фигня (может хитрость?) от R*. В оригинальных скриптах повсюду конструкции вида
:OLOLO // вайт не ставим! if ... // здесь должно быть условие с NOT впереди else_jump @ ... // Аналог jf, jump @OLOLO @ ... // Вот такие пироги
Об этом писал симэн, когда ему задавали примерно такой же вопрос.
Если ты хотел спросить как делают while true ... end то работает просто.
while true // Пока действие истинно, будет выполняться ... // Любой код (весь скрипт) end
Offline
Den_spb, насчёт этого опкода:
0604: get_Z_angle_for_point 0@ 1@ store_to 2@ты сказал:
Den_spb wrote:
угол будет получен в пределах 0-90 градусовпоэтому я не стал его проверять, но сейчас всё же решил проверить и как оказалось он работает на все 360 градусов, короче говоря, это то что мне было нужно)) спасибо большое, очень выручил!)
Ты не совсем меня понял. Мера угла зависит от способа применения данного опкода. Ну хорошо, что теперь разобрался.
и ещё, объясните пожалуйста, как правильно пользоваться while...end
Прочитай внимательно раздел Кодинг-Циклы в справке и всё поймёшь.
Есть одна фигня (может хитрость?) от R*. В оригинальных скриптах повсюду конструкции вида
Где, например, есть такая конструкция?
Offline
Прочитай внимательно раздел Кодинг-Циклы в справке и всё поймёшь.
хех...я прочитал...но почему то у меня вылетает когда я пишу...причём вылетает когда проигрывается именно эта анимация...
:LOOK wait 0 while actor.Animation($PLAYER_ACTOR) == "ROLL" 068D: get_camera_position_to 1@ 2@ 3@ 068E: get_camera_target_point_to 4@ 5@ 6@ 0063: 4@ -= 1@ // (float) 0063: 5@ -= 2@ // (float) 0063: 6@ -= 3@ // (float) 050A: 7@ = distance_between_XYZ 0.0 0.0 0.0 and_XYZ 4@ 5@ 6@ 7@ /= 100.0 0073: 4@ /= 7@ // (float) 0073: 5@ /= 7@ // (float) 005B: 4@ += 1@ // (float) 005B: 5@ += 2@ // (float) actor.StorePos($PLAYER_ACTOR, 10@, 11@, 12@) 0063: 4@ -= 10@ // (float) 0063: 5@ -= 11@ // (float) 0604: get_Z_angle_for_point 4@ 5@ store_to 8@ actor.Angle($PLAYER_ACTOR) = 8@ end jump @LOOK
насчёт while true...end
я так понял тут надо останавливать цикл внутри его тела, судя по всему с помощью проверок и Break...
насчёт R* штучек - у них в одном потоке либо один wait 0, либо они пишут его так))) -
:PSAVE1_1049 if 83D9: not save_done jf @PSAVE1_1073 wait 0 jump @PSAVE1_1049
хотя нет, вот один -
:TRAINSL_11 wait 0 if Player.Defined($PLAYER_CHAR) jf @TRAINSL_115 if Actor.Driving($PLAYER_ACTOR) jf @TRAINSL_115 if Actor.DrivingVehicleType($PLAYER_ACTOR, #STREAKC) jf @TRAINSL_115 0926: $SCRIPT_STATUS = external_script_status 33 (TRAINS) if $SCRIPT_STATUS == 0 jf @TRAINSL_115 08A9: load_external_script 33 (TRAINS) if 08AB: external_script 33 (TRAINS) loaded jf @TRAINSL_115 0913: run_external_script 33 (TRAINS) :TRAINSL_115 jump @TRAINSL_11
кстати, они не ставят jf на начало, а в той метке куда стоит jf (@TRAINSL_115 в нашем случае) стоит jump на первую метку и так все jf-ы которые должны попасть на начало например...почему они делали именно так?)))
и есть ли способ избавиться от этой задержки в циклической проверке??
Last edited by BoPoH (26-10-2010 17:38)
Offline