You are not logged in.
По привычке из Discord’а хотел нажать «Ответить» или поставить реакцию. Надо переучиваться обратно.
А ещё надо обязательно упомянуть разрабатываемый Seemann’ом новый компилятор Somersault, доступный как на сайте, так и в Sanny Builder 4 в качестве отдельного режима редактирования. С интересом слежу за его развитием и надеюсь на ещё большую поддержку SB4.
P.S. Если форумы будут оживляться дальше, надо и часовые пояса обновить, а то мне для соответствия пришлось Африку поставить.
Я! Надеюсь, кто-нибудь ещё подтянется. А пока кину сюда свой скрипт снежка, протестирую подсветку. Да и вообще вспомню, каково это, на форумах писать.
{$CLEO} // Script by Vital (Vitaly Pavlovich Ulyanov) script_name 'SNOW' const minStartX = 10.0 const maxStartX = 630.0 const minStartY = -15.0 const maxStartY = -350.0 int i // `for` loop counter int snow = 0 // Snow activation flag float x[10] // X positions of snowflakes float y[10] // Y positions of snowflakes float mx, my // Mouse X and Y offsets while true wait 0 if not Player.IsPlaying(0) then continue end if Pad.TestCheat("SNOW") then if snow == 0 then snow = 1 for i = 0 to 9 // Reset snowflakes position to random starting points x[i] = Math.RandomFloatInRange(minStartX, maxStartX) y[i] = Math.RandomFloatInRange(minStartY, maxStartY) end Text.PrintStringNow("Snow ~r~ON~s~ [Script by ~y~Vital~s~]", 3000) else snow = 0 Text.PrintStringNow("Snow ~r~OFF", 3000) end end if snow == 1 then for i = 0 to 9 // X coordinate is the value of sine function mx, my = Mouse.GetMovement() float s = Math.Sin(y[i]) float ms = Math.Sin(mx) // A bit of randomisation for both X and Y movement float r = Math.RandomFloatInRange(0.25, 0.7) float ySpeed = Math.RandomFloatInRange(0.3, 0.5) s *= r s += ms // Timed (fps-independent) addition x[i] +=@ s y[i] +=@ ySpeed if and // Current snowflake is not ouf of borders y[i] < 448.0 x[i] > 0.0 x[i] < 640.0 then if y[i] > -10.0 then Text.UseCommands(true) Text.SetScale(0.4, 1.8) Text.SetDropshadow(1, 0, 148, 255, 150) Text.Display(x[i], y[i], "PAGE_00") Text.UseCommands(false) end else // Reset snowflake's position to a random starting point x[i] = Math.RandomFloatInRange(minStartX, maxStartX) y[i] = Math.RandomFloatInRange(minStartY, maxStartY) end end end end
P.S. Не хватает новой подсветки синтаксиса. Но это всё со временем придёт, а пока хватает или SCM, или CPP.
P.P.S. Немного соскучился по длинным осмысленным сообщениям. Форумы к ним подталкивают получше, а то вот
такая
манера
писать
тексты
уже порядком
за-
дол-
ба-
ла
.
Seemann wrote:SanyaSFM wrote:Нет опкода для проверки: проденная ли такая-то такая-то миссия?
Можно и с номером миссии.
Обрыскал все опкоды связанные с миссиями, но ничего так и не нашёл.это контролируется глобальными переменными. Обычно в конце миссии есть переменная типа $THIS_MISSION_PASSED = 1
Значит нету, думаю тут, что мне вы скинули, это типа: если 0 - не пройдена (наверное), если: 1 - то пройдена.
То есть не смысла подставлять номер миссии.
Когда там новая версия саньки билдера будет?
Жду не дождусь подсветки констант, я бы сам это сделал, да вроде не открытого кого исходного, да я и не программист, в дельфи только баловался, язык паскаля и остальные тоже - не знаю.
Почему же нету? Просто способ не самый удобный. Но вот я открыл main.scm, нашёл миссию “Big Smoke”, в конце неё обнаружил строчку:
$INTRO_TOTAL_PASSED_MISSIONS += 1
Далее в поиске этой переменной по файлу отыскал такое условие:
if $INTRO_TOTAL_PASSED_MISSIONS == 1 jf @INT_292 $ONMISSION = 1 00BA: show_text_styled GXT 'INTRO_2' time 1000 style 2 // Pa??ep gosub @SUB_CJ_GOTO_RYDER_HOUSE start_mission 12 // Ryder
Из чего делаю вывод, что после прохождения миссии “Big Smoke” значение переменной должно равняться единице. Таким же образом эту же переменную я могу проверить и в своём скрипте, таким образом привязывая какие-то события или возможности к ходу сюжета.
В этом варианте внутри Check не нужны 0485 и 059A, т.к. опкод jump_if_false (который используется в циклах) читает результат последней проверки, который обновляется после применения любого условного опкода.
Ого, этого не знал, спасибо! А это не может сработать в условном gosub не в цикле? У меня такая (гуманитарная) логика: если в цикле при условном gosub можно обойтись без return_true/false, то без них можно обойтись везде, так как высокоуровневые конструкции игрой "разбираются" на низкоуровневые конструкции с метками, то есть на "начальном" уровне они ничем не отличаются друг от друга. Если так, то зачем нужны 0485 и 059А?
Но скорее всего, я просто недопонимаю.
Ещё раз благодарю за этот нюанс!
В циклах (while, repeat) ещё можно использовать условный gosub.
while gosub @Check wait 0 //действия end :Check if and //или if or //условие 1 //условие 2 then 0485: return_true else 059A: return_false end return
У меня работало, это удобно. Можно и внутрь while true вставить условия, как показал DK22Pac.
Пара вопросов:
1. Как проверить, что актёру установлен иммунитет к выстрелам?
2. Можно ли проверить, что никакие кнопки не нажимались в течение определённого времени, к примеру, одной минуты?Заранее спасибо.
1) думаю, вот это может помочь (из GTA Modding):
CPed +0x42 = [byte] Is the BP/EP/FP/DP (special flags) status of the player as follows: Bit 1 = makes ped soft (ie. can move through walls and everything) (noclip in other words) Bit 2 = freezes ped (ie. ped cannot walk) Bit 3 = bullet-proof Bit 4 = flame-proof Bit 5 = collision-proof Bit 6 = MP-proof (MP) Bit 7 = ? Bit 8 = explosion-proof
Тут понадобятся структура актёра (0A96) + указанное смещение, считывание из памяти (0A8D) и работа с битами переменной (08B7), поскольку именно в них записаны иммунитеты;
2) если речь об обычных игровых клавишах, то можно сделать так:
- обнулить таймер 32@
- создать флаг (не)нажатия //если есть решение получше, можно и без него, например, сделать условный gosub с циклом
- в цикле for проверять, нажата ли одна из клавиш (номер клавиши = счётчик цикла), если да, делаем провал условия.
Ура! Поздравляю с юбилеем программы! Без неё я бы никогда не сделал многого, прежде всего, не стал бы делать скрипты.
Seemann'у лично пожелаю дальнейших успехов, счастья и всего наилучшего! Пусть SB и далее развивается и совершенствуется, радуя скриптеров всех уровней!
Такая проблема. Делаю для GTA VC скрипт, дающий возможность управлять радиостанцией "MP3 Player": одна клавиша включает следующую композицию, другая - случайную. Ибо такой возможности в игре нету, в отличие от SA. И вроде бы всё ничего, работает, но есть одно важное "но". Чтобы услышать эффект переключения, нужно заново прокрутить все радиостанции до проигрывателя своей музыки или выйти из машины и сесть снова. В связи с этим вопрос звучит так: как перезагрузить радио "MP3 Player"?
Усугубляется всё тем, что опкод 041Е, который ставит радиостанцию, не может поставить станцию 9, то есть эту самую. Когда стоит параметр 9, опкод меняет его сразу на 10 - выключить радио. Я попробовал получить и поставить радиостанцию через память машины, но не вышло. Я попробовал сначала отключить радио опкодом 041Е, а потом через память насильно поставить этот проигрыватель, но тщетно.
Буду рад, если кто поможет. При публикации скрипта (и/или при создании видео про него) обязательно упомяну, это само собой разумеется. Тему создал потому, что вопрос не самый простой, на мой взгляд, но если всё проще, и новая тема зря создана, то прошу прощения.
Если нет никакой возможности как-то адекватно выбрать радиостанцию или перезагрузить её, то есть запасной, хотя и странноватый вариант: если имеется возможность как-то сымитировать нажатие клавиши "Следующая радиостанция", то можно поставить опкодом 041Е радио №8, а потом имитация этой самой клавиши переключит радио на проигрыватель.
Заранее спасибо всем откликнувшимся!
https://sannybuilder.com/dev/sa_opnames.txt
оригинальные рокстаровские названия скриптовых команд, которые были опубликованы вместе с SA Mobile.
Спустя много лет интересно сравнить, насколько точны или наивны были наши предположения о смысле тех или иных опкодов.
Ух ты! Я, конечно, понимаю, какая это трудная работа, но планируется ли полная замена текста опкодов на новый? Или просто будут исправлены неточности и unknown'ы?
Как бы то ни было, это уже радует, информация крайне полезная.
Как вариант прочесовать пулл снарядов (0xC891A8) ловить там те, что выпущинные твоим Rustler и выгружать их.
Спасибо, стоит попробовать!
Снова я со своими вопросами
1) Можно ли отключить звук (оповещение в виде постоянного писка) приближения вражеской ракеты с теплонаведением, который проигрывается в транспорте?
2) Есть ли возможность отключить стрельбу ракетами у самолёта Rustler после применения опкода атаки игрока? То есть после опкода 08А2 самолёт, не имеющий ракет, стреляет как из пулемёта, так и ракетами, что нелогично. Пробовал другой опкод с аналогичным действием, но результат тот же.
Заранее спасибо!
Спасибо! Помогло именно это, реакция 1022 на событие 36.
Всё работает прекрасно! Спасибо!
Теперь появился другой вопрос: есть скрипт, создающий машину, которая ездит за игроком, в ней два актёра, но тот, что на пассажирском сидении, не стреляет по ненавистным ему людям, хотя, по логике, 077А должен позволять это делать. Пробовал опкод 0713 без параметров объекта обстрела, но не помогает. Проблема как раз в том, чтобы заставить пассажира стрелять по усмотрению его ИИ, а не по опкоду. Заранее благодарю!
Прилагаю код:
//$PLAYER_ACTOR $PLAYER_GROUP {$CLEO} 0000: while true wait 0 if player.Defined(0) then if and not actor.Driving($PLAYER_ACTOR) 0ADC: test_cheat "CAR" then model.Load(#ALPHA) model.Load(#FAM1) model.Load(#FAM2) model.Load(#TEC9) 038B: load_requested_models actor.StorePos($PLAYER_ACTOR,0@,1@,2@) 02C1: store_to 0@ 1@ 2@ car_path_coords_closest_to 0@ 1@ 2@ car.Create(3@,#ALPHA,0@,1@,2@) car.SetImmunities(3@,1,1,1,1,1) 0129: 4@ = create_actor_pedtype 8 model #FAM1 in_car 3@ driverseat 01C8: 5@ = create_actor_pedtype 8 model #FAM2 in_car 3@ passenger_seat 0 car.DoorStatus(3@,2) 077A: set_actor 5@ acquaintance 1 to_actors_pedtype 0 // see ped.dat 077A: set_actor 5@ acquaintance 4 to_actors_pedtype 6 // see ped.dat 077A: set_actor 5@ acquaintance 4 to_actors_pedtype 7 // see ped.dat 077A: set_actor 5@ acquaintance 4 to_actors_pedtype 9 // see ped.dat actor.GiveWeaponAndAmmo(4@,Tec9,99999) actor.GiveWeaponAndAmmo(5@,Tec9,99999) model.Destroy(#ALPHA) model.Destroy(#FAM1) model.Destroy(#FAM2) model.Destroy(#TEC9) car.SetDriverBehaviour(3@,DriveToPlayer) car.SetMaxSpeed(3@,50.0) marker.CreateAboveCar(6@,3@) marker.SetColor(6@,1) while true wait 0 if or not player.Defined(0) car.Wrecked(3@) not actor.InCar(4@,3@) not actor.InCar(5@,3@) actor.Dead(4@) actor.Dead(5@) then break end end car.SetImmunities(3@,0,0,0,0,0) car.DoorStatus(3@,1) marker.Disable(6@) actor.RemoveReferences(4@) actor.RemoveReferences(5@) car.RemoveReferences(3@) end end end
Спасибо большое! Буду пробовать, если что будет не так, напишу. Ещё раз благодарю за помощь!
Есть вопрос относительно textbox, если точнее, относительно опкода 0АСА. Можно ли вывести textbox без звука или как-то сразу выключить звук, чтобы его не было? Дело в том, что в моей модификации textbox появляться может довольно часто, чтобы звук надоел, хотя саму надпись можно и не заметить.
Опкод 03FE предназначен для всех актёров, кроме игрока.
Никто не мешает использовать простую математику для установления количества денег игрока:
0@ = player.Money(0) 0@ *= -1 player.Money(0) += 0@ player.Money(0) += 150 0A93: end_custom_thread
Всё просто: получаем кол-во денег игрока и записываем в переменную 0@; умножаем её на -1; прибавляем к текущим деньгам игрока ту же сумму со знаком "-", получается как в математике: x - x = 0; прибавляем нужное количество денег. Всё, старая сумма полностью стирается, а её заменяет новая. То же самое с бронёй, а вот здоровье вроде можно ставить на любой уровень без этих вычитаний.
А можно ли в 3 и VC добавить cleo-переменные? Это был бы аналог массивов (хотя бы примитивный), потому что они идут в опкодах по номерам (0AB3: var 0 = 10). И таким образом можно было бы записать, к примеру, хендлы актёров в цикле for, где счётчик был бы и номером cleo-переменной.
Кстати, говорится, что такие переменные сохраняются в cleo сейвах. У каждого скрипта свой сейв, или могут быть конфликты скриптов при использовании одних и тех же номеров cleo-переменных? Скажем, один скрипт будет брать переменные 0-10, другой возьмёт те же, тогда будут конфликты, или каждый скрипт имеет свой запас cleo-переменных?
Я, конечно, много говорю по мелочам, так что на это обращайте меньше внимания, у многих есть идеи куда более приоритетные. Хотелось бы, чтобы не было глюков с поиском опкодов: там вместо фразы "Найдено (кол-во) опкодов" стоит только "Найде", а также нету полосы прокрутки, и последний в списке опкод частично скрыт. Это просто мелкие неудобства.
А вот идея относительно кода - здорово было бы добавить массивы в GTA 3 и VC, так как вряд ли разработчики обошлись без них при создании игр (в чём я могу ошибаться, конечно). DK22Pac показывал способ, который может заменить стандартные массивы, но было бы гораздо удобнее иметь и обычный вариант, тем более, если SB начинают изучать новички, совсем не понимающие работы с памятью (впрочем, я в этом тоже не самый понимающий, но тот алгоритм вполне хорош).
Мда, с поиском опкодов всё не очень хорошо. Мало того, что надпись на корявом языке (терпимо более-менее, скриншот приложил в предыдущем сообщении), но ещё есть проблемы:
- нету прокрутки, потому последние результаты остаются почти скрытыми границами окна поиска
- пропало отображение количества найденных опкодов
Есть ещё пожелание по поиску: хорошо бы сделать ссылку на GTAG прямо в строке поиска, чтобы пользователь мог нажать на неё и увидеть детальное описание. Или добавить ещё одну строку поиска для этой цели.
Не лишним было бы ещё разделение обычных опкодов от cleo для облегчения поиска (по выбору: все опкоды, только cleo или только стандартные).
Как всегда, генератор идей запустился
Если всё это нереализуемо или просто ненужно, то не сердитесь, это всего лишь мелкие предложения.
@Seemann - @Seemann - здорово, уже новая версия
Начинаем искать мелкие недочёты:
Картинка
Попутно хотелось бы предложить слегка расширить количество запоминаемых последних файлов (если возможно) и сделать запоминание макросов. Кстати, неплохо было бы сделать удаление макросов без необходимости менять сам файл macroes.
Если в дальнейшем будут какие-то идеи или находки, обязательно сообщу.
@Seemann - я бы сказал, что и к тому, и к другому, так как декомпиляция всё же иногда необходима, так что выбор в debug-настройках будет полезен.
Кстати, неужели невозможно сделать компиляцию таким образом, чтобы высокоуровневые конструкции и циклы всё-таки сохранялись, или это уже особенности внутри игры/программы? Немалое количество людей на форумах разных сайтов просят помощи со скриптами, исходников которых у них нету, потому людям приходится иметь дело с декомпилированным вариантом, который не так удобен для восприятия.
В общем, всё на усмотрение, ни к чему не хочу принуждать, а то, если учитывать все просьбы, даже малейшие, улучшение программы растянулось бы на века.
@Seemann - я никуда не спешу с этим, к тому же я имею в виду те опкоды, которые уже имеют в своём тексте отображение записей. К примеру, после 03Е5 следует стандартный текст про то, как игрок может поднять уровень уважения. То есть, когда-то эта идея начала работать, и содержимое текста записалось в opcodes.txt, что порой неприятно при переходе на другую строку, приходится жать End, только потом Enter. Но это, конечно, так, придирка больше, нежели что-то серьёзное, описание опкодов можно и подредактировать, как я и сделал, но при каждом обновлении эти комментарии будут возвращаться. Но это, как я уже сказал, в последнюю очередь, лучше обратить внимание на что-то более стоящее и важное пока что.
@Seemann - спасибо, удачи в улучшении!
@Seemann - сейчас перебрал все опкоды из opcodes.txt в SB, вот результаты:
00F1: actor $PLAYER_ACTOR sphere 0 near_point 540.0 2000.0 stopped_in_car 072D: unknown_check %1d% %2d% %3d% %4d% %5d% %6h% 072E: unknown_check %1d% %2d% %3d% %4d% %5d% %6h% %7d% %8d% 0AF5: write_string "new string value" to_ini_file "cleo\config.ini" section "SectionName (незавершённая строка)
Вот всё, что я нашёл. Хорошо, что всё опкоды есть в файле .txt, иначе пришлось бы по одному копировать в SB
@Den_spb - спасибо за совет, помогло.
А что насчёт отображения GXT записей в тексте опкодов? Они идут как комментарий, при этом иногда мешая восприятию, впрочем, это далеко не первостепенная проблема.
@Seemann - @Seemann - хотелось бы сообщить о небольшой проблеме, которая, впрочем, неприятная. Дело в том, что при поиске опкодов немногие из них не до конца написаны, например:
0B01: delete_directory
Совершенно без параметров, хотя их должно быть два.
Хотел бы ещё попросить даже, а не сообщить, убрать отображение содержания GXT записей в опкодах: это иногда мешает. Здорово было бы сделать отображение таких записей в виде подсказок при нажатии Ctrl+Пробел, если это возможно.
Как идея как можно больше опкодов (можно, например, только CLEO) в виде классов, как actor., к примеру. Было бы очень удобно, к тому же похоже на GTA IV (C#). Но это по усмотрению, конечно.
Также хотел спросить, с чем связано то, что cleo текст (0ACA и подобные) отображают текст лишь заглавными буквам, несмотря на то, как написан текст в программе? У меня стоит русификатор от SanLtd, он поддерживает как заглавные, так и строчные английские/русские символы.
Заранее спасибо за ответы и помощь!