You are not logged in.
Pages: 1
Здравствуйте. Я пишу скрипт подрывника. Суть: в игре есть 200 спрятанных пакетов, но их охраняет актёр. При сборе каждого пакета этот актёр появляется и агрится на игрока, пока игрок не умрёт. Актёру даны гранаты для нападения и иммунитет от взрывов (чтобы сам не подорвался). Когда игрок соберёт все пакеты то скрипт отключится. Но пока я делал скрипт я нашёл много проблем, которые я не знаю как решить. Все проблемы описаны в архиве с помощью картинок.
https://cloud.mail.ru/public/naWb/2ygzNiVEH
Подскажите пожалуйста все возможные способы и пути решения, чтобы подрывник стал стабильнее.
Это текущий скрипт подрывника:
{$CLEO}
0000:
:HIDBOMB
thread 'HIDBOMB'
wait 0
if and
0256: player 0 defined
$flag_player_on_mission == 0
jf @HIDBOMB
03E1: $PACK_1 = packages_found
if
$PACK_1 == 200
then
end_thread
else
repeat
wait 0
03E1: $PACK_2 = packages_found
until 803A: not $PACK_2 == $PACK_1 // $ == $ int
if and
001C: $PACK_2 > $PACK_1 // $ > $ int
$flag_player_on_mission == 0
then
023C: load_special_actor 1 'BOMBER'
0247: request_model #GRENADE
repeat
wait 0
until 023D: special_actor 1 loaded
repeat
wait 0
until 0248: model #GRENADE available
gosub @RANDPLACE // returns 0@ 1@ 2@ (X Y Z)
009A: $BOMBER = create_actor 18 #SPECIAL01 at 0@ 1@ 2@
0223: set_actor $BOMBER health_to 200
01B2: give_actor $BOMBER weapon 11 ammo 9999
0249: release_model #GRENADE
02AB: set_actor $BOMBER immunities 0 0 1 0 0
0187: $MARKER_BOMBER = create_marker_above_actor $BOMBER
01CC: actor $BOMBER kill_player 0
while 00A2: actor $BOMBER alive
if or
8256: not player 0 defined
00E9: player 0 0 $BOMBER radius 5.0 5.0
8184: not actor $BOMBER health >= 75
$flag_player_on_mission <> 0
then
02AB: set_actor $BOMBER immunities 0 0 0 0 0
00A0: store_actor $BOMBER position_to 0@ 1@ 2@
020C: create_explosion 8 at 0@ 1@ 2@
break
else
if
02A0: actor $BOMBER stopped
then
0054: store_player 0 position_to 0@ 1@ 2@
0239: actor $BOMBER run_to 0@ 1@
else
if
00E9: player 0 0 $BOMBER radius 25.0 25.0
then
01CA: actor $BOMBER kill_player 0
end
end
if and
80E9: not player 0 0 $BOMBER radius 40.0 40.0
82CB: not actor $BOMBER bounding_sphere_visible
then
gosub @RANDPLACE
if
00A2: actor $BOMBER alive
then
00A1: put_actor $BOMBER at 0@ 1@ 2@
end
end
end
wait 0
end
0164: disable_marker $MARKER_BOMBER
01C2: mark_actor_as_no_longer_needed $BOMBER
0296: unload_special_actor 1
else
jump @HIDBOMB
end
end
jump @HIDBOMB
:RANDPLACE
repeat
wait 0
0208: 0@ = random_float -20.0 20.0
0208: 1@ = random_float -20.0 20.0
04C4: create_coordinate 0@ 1@ 2@ from_actor $PLAYER_ACTOR offset 0@ 1@ 0.0
0209: 3@ = random_int 0 2
if
3@ == 0
then
02C0: set 0@ 1@ 2@ to_ped_path_coords_closest_to 0@ 1@ 2@
else
02C1: set 0@ 1@ 2@ to_car_path_coords_closest_to 0@ 1@ 2@
end
until 80C2: not sphere_onscreen 0@ 1@ 2@ 4.0
return
end_thread
Last edited by Remca12 (03-12-2020 09:50)
Offline
Для начала нужно избавиться от всех глобальных переменных, кроме $PLAYER_ACTOR.
Переменную $flag_player_on_mission заменить на $onmission
end_thread заменить на 0A93: terminate_this_custom_script
Offline
Спасибо, но это всё сразу в main.scm-е пишется. У меня 2 основные проблемы: подрывник после своего первого подрыва становится бычным трусливым педом и если его ударить, то он будет убегать от игрока, а если он где-то затупит то может не найти игрока, поэтому раньше я давал ему проверку на видимость игрока.
Я пробовал вот так, когда подрывник тупит, чтобы подрывник сразу смотрел в сторону игрока.
if 8123: actor $bomber spotted_player $player_char then 020f: actor $bomber look_at_player $player_char end
Необходимо чтобы подрывник подрывался пока игрок жив.
Но самое странное что подрывник не может кинуть гранату, он ее только хочет кинуть, а потом дергается, в итоге гранату он кинуть не может и она не взрывается.
Last edited by Remca12 (03-12-2020 17:31)
Offline
это всё сразу в main.scm-е пишется
не совсем очевидно из вашего примера, в котором есть директива {$CLEO}, ну да ладно. Из того что бросилось в глаза, подрывник создается с типом 18. В GTA 3 для создания скриптовых персонажей в основном используется тип 21 (Special). Попробуйте с этим типом, может поведение будет иное.
Offline
Спасибо за пояснения, подрывник себя должен подрывать пока он жив и игрок жив, но если хоть кто-то из них умрёт, то подрывник больше не будет нужен.
Осталась лишь самая странная проблема: подрывник себя подрывает только 1 раз, а потом у него стирается память, а когда именно стирать его память (имеется ввиду все сведения об актёре) я не знаю. Когда это лучше делать ?
Оказывается подрывник дёргался из-за того что я его заставлял бежать к игроку, в случае если игрок далеко стоит, и тогда подрывник тупит.
Закомментировав эту часть кода подрывник стал кидать нормально гранаты:
if
02A0: actor $BOMBER stopped
then
0054: store_player 0 position_to 0@ 1@ 2@
0239: actor $BOMBER run_to 0@ 1@Я забыл где надо смотреть типы актёров.
Last edited by Remca12 (04-12-2020 09:12)
Offline
Тип актера задается при создании
009A: $BOMBER = create_actor 18 #SPECIAL01 at 0@ 1@ 2@
тут 18 - это параметр PedType
вот документация:
http://gtamodding.ru/wiki/Ped_Type - (неправильно указан тип 19, должно быть 21)
https://docs.sannybuilder.com/v/ru/scm- … 3/pedtypes
https://gtamods.com/wiki/Ped_type - тут наиболее полная информация
подрывник себя подрывает только 1 раз, а потом у него стирается память
имеется в виду эта часть?
then
02AB: set_actor $BOMBER immunities 0 0 0 0 0
00A0: store_actor $BOMBER position_to 0@ 1@ 2@
020C: create_explosion 8 at 0@ 1@ 2@
break <---- прерываем цикл
....
0164: disable_marker $MARKER_BOMBER
01C2: mark_actor_as_no_longer_needed $BOMBER <--- приходим сюда
0296: unload_special_actor 1
я думаю что если убрать break подрывник будет пытаться подорвать себя, пока не умрет, после чего цикл while 00A2: actor $BOMBER alive прекратится сам и будет вызван 01C2, чтобы освободить память игры.
Offline
Спасибо за типы, возьму на заметку)
Я убирал break, но при первом же подрывании себя подрывник сдох, а затем я закомментировал строку где снимается иммунитет подрывника от взрыва, но тогда он себя подрывает кучу раз стоя на одном месте. А подрывник должен подрываться если игрок близко с подрывником, но если подрывник ещё жив, то он опять должен побежать к игроку чтобы подорваться до тех пор пока он сам не умрет.
Если цикл не прерывать то за подрывником будет хвост взрывов пока он бежит, а он не побежит если к нему не подойти. Но если цикл прерывать то он себя подорвет лишь 1 раз.
Last edited by Remca12 (04-12-2020 16:42)
Offline
но тогда он себя подрывает кучу раз стоя на одном месте
а кто ему говорит, что нужно бежать? По условию взрыв происходит если подрывник находится рядом с игроком. Если игрок стоит на месте, что должно произойти? Подрывник ведь тоже будет стоять? Наверно, есть смысл переместить взрыв (опкод 020C) после проверки 02A0: actor $BOMBER stopped.
Т.е. логика должна быть примерно такая
создали подрывника
запускаем бесконечный цикл (while true)
проверяем, если игрок или подрывник умер - делаем break
проверяем остановился ли подрывник рядом с игроком
если да, то создаем explosion
если нет, заставляем его бежать
делаем паузу на 2 секунды (тогда серия взрывов будет реже)
конец цикла
очистка
Offline
Измененный код подрывника. Я не останавливаю игрока, так как это мешает ему кидать гранаты, вместо этого я его заставляю посмотреть в сторону игрока.
Last edited by Remca12 (05-12-2020 09:30)
Offline
Код обновлён. Вроде как всё верно. Если что-то неверно - слушаю.
Last edited by Remca12 (05-12-2020 09:29)
Offline
но тогда он себя подрывает кучу раз стоя на одном месте
а кто ему говорит, что нужно бежать? По условию взрыв происходит если подрывник находится рядом с игроком. Если игрок стоит на месте, что должно произойти? Подрывник ведь тоже будет стоять? Наверно, есть смысл переместить взрыв (опкод 020C) после проверки 02A0: actor $BOMBER stopped.
Т.е. логика должна быть примерно такая
создали подрывника
запускаем бесконечный цикл (while true)проверяем, если игрок или подрывник умер - делаем break
проверяем остановился ли подрывник рядом с игроком
если да, то создаем explosion
если нет, заставляем его бежать
делаем паузу на 2 секунды (тогда серия взрывов будет реже)конец цикла
очистка
Как проверить что игрок на каком-то острове ? Я пытаюсь телепортировать актёра на тот же остров на котором находится игрок опкодом 03fc ? Но он не условный, а других способов я не знаю. Гта 3, если что.
Offline
03C6: current_island == 1
Offline
03C6: current_island == 1
Пока я тестировал скрипт, вышла интересная проблема: если игрок собрал спрятанный пакет на одном острове и переместился на другой остров, неважно как (додо, noclip и т.д.), то актер будет телепортироваться. Но находится он будет в земле, а не на путях педов и машин. Код тот же самый. (пока не измененный)
Offline
Помогите пожалуйста. Я пытаюсь создавать случайную лодку, но пока гта 3 выдаёт ошибку на опкод проверяющий что игрок в любой лодке. Я кучу комментариев оставил.
:HIDBOMB
thread 'HIDBOMB'
wait 0
0AC8: 4@ = allocate_memory_size 12
0AC8: 5@ = allocate_memory_size 12
0085: 6@ = 4@
0085: 7@ = 5@
0A8C: write_memory 6@ size 4 value -1337.0 virtual_protect 1
0A8C: write_memory 6@ size 4 value -1488.0 virtual_protect 1
0A8C: write_memory 6@ size 4 value 34.0 virtual_protect 1
0A8C: write_memory 7@ size 4 value 1337.0 virtual_protect 1
0A8C: write_memory 7@ size 4 value 1488.0 virtual_protect 1
0A8C: write_memory 7@ size 4 value 69.0 virtual_protect 1
0AA5: call_function 0x563C30 num_params 3 pop 0 34 5@ 4@
if and
0256: player 0 defined
$flag_player_on_mission == 0
jf @HIDBOMB
03E1: $PACK_1 = packages_found
if
$PACK_1 == 200
then
end_thread
else
repeat
wait 0
03E1: $PACK_2 = packages_found
until 803A: not $PACK_2 == $PACK_1 // $ == $ int
if and
001C: $PACK_2 > $PACK_1 // $ > $ int
$flag_player_on_mission == 0
then
023C: load_special_actor 1 'BOMBER'
0247: request_model #GRENADE
0247: request_model #PREDATOR
0247: request_model #GHOST
repeat
wait 0
until 023D: special_actor 1 loaded
repeat
wait 0
until 0248: model #GRENADE available
repeat
wait 0
until 0248: model #PREDATOR available
repeat
wait 0
until 0248: model #GHOST available
gosub @RANDPLACE // returns 0@ 1@ 2@ (X Y Z)
//00A0: store_actor $BOMBER position_to 0@ 1@ 2@ //float
//0AD1: show_formatted_text_highpriority "%.2f %.2f %.2f" time 20000 0@ 1@ 2@
009A: $BOMBER = create_actor 21 #SPECIAL01 at 0@ 1@ 2@
03FC: actor $BOMBER bind_to_current_island 0
0223: set_actor $BOMBER health_to 200
01B2: give_actor $BOMBER weapon 11 ammo 9999
0249: release_model #GRENADE
02AB: set_actor $BOMBER immunities 0 0 1 0 0
0187: $MARKER_BOMBER = create_marker_above_actor $BOMBER
01CC: actor $BOMBER kill_player 0
while true
wait 0
if or
0117: player $PLAYER_CHAR wasted
0130: player $PLAYER_CHAR busted
80A2: actor $BOMBER alive
then
02AB: set_actor $BOMBER immunities 0 0 0 0 0
break
end
if or
00E9: player 0 0 $BOMBER radius 5.0 5.0
8184: not actor $BOMBER health >= 5
$flag_player_on_mission <> 0
then
00A0: store_actor $BOMBER position_to 0@ 1@ 2@
020C: create_explosion 0 at 0@ 1@ 2@
else
if and
80E9: not player 0 0 $BOMBER radius 20.0 20.0
8123: actor $BOMBER spotted_player $player_char
then
020F: actor $BOMBER look_at_player $player_char
00A0: store_actor $PLAYER_ACTOR position_to 0@ 1@ 2@
0239: actor $BOMBER run_to 0@ 1@
01CC: actor $BOMBER kill_player 0
end
if and
80E9: not player 0 0 $BOMBER radius 40.0 40.0
82CB: not actor $BOMBER bounding_sphere_visible
then
gosub @RANDPLACE
if
00A2: actor $BOMBER alive
then
00A1: put_actor $BOMBER at 0@ 1@ 2@
01CC: actor $BOMBER kill_player 0
end
end
end
end //конец цикла
wait 2000
end
end
if //условия для езды лодками за актёром
04A8: player $PLAYER_CHAR driving_boat //если Клод в любой лодке
//пока что игра ругается на опкод 04A8.
//0056: player $PLAYER_CHAR 0 -230.0 255.0 -210.0 275.0 //и в зоне (хз какой,
// наверное что-то другое понадобится)
then //то
gosub @RANDCAR
end
0164: disable_marker $MARKER_BOMBER
0164: disable_marker $MARKER_BOMBER1
01C2: mark_actor_as_no_longer_needed $BOMBER
0296: unload_special_actor 1
jump @HIDBOMB
:RANDPLACE
repeat
wait 0
0208: 0@ = random_float -20.0 20.0
0208: 1@ = random_float -20.0 20.0
04C4: create_coordinate 0@ 1@ 2@ from_actor $PLAYER_ACTOR offset 0@ 1@ 0.0
0209: 3@ = random_int 0 2
if
3@ == 0
then
02C0: set 0@ 1@ 2@ to_ped_path_coords_closest_to 0@ 1@ 2@
else
02C1: set 0@ 1@ 2@ to_car_path_coords_closest_to 0@ 1@ 2@
end
until 80C2: not sphere_onscreen 0@ 1@ 2@ 4.0
return
:RANDCAR //случайная злая лодка.
03C1: $BOMBER_CAR = player $PLAYER_CHAR car_no_save
repeat
wait 0
00A0: store_actor $PLAYER_ACTOR position_to 0@ 1@ 2@
04C4: create_coordinate 0@ 1@ 2@ from_actor $PLAYER_ACTOR offset 0@ 1@ 0.0
0209: 9@ = random_int 0 2
if
9@ == 0
then //по задумке случайная лодка поплывёт за игроком
00A5: $BOMBER_CAR = create_car #GHOST at 0@ 1@ 2@
0187: $MARKER_BOMBER1 = create_marker_above_actor $BOMBER_CAR
else //а за рулём лодки будет подрывник (актёр)
00A5: $BOMBER_CAR1 = create_car #PREDATOR at 0@ 1@ 2@
end
until 80C2: not sphere_onscreen 0@ 1@ 2@ 4.0 //забыл для чего этот конец.
//после спавна гоняем лодки за актёром: полицейка стреляет, а лодка-призрак
//только плывёт сподрывником
//так как хватит близости чтобы подрывник подорвал и лодку свою и лодку игрока.
0AC9: free_allocated_memory 4@
0AC9: free_allocated_memory 5@
end_thread
Offline
04A8: player $PLAYER_CHAR driving_boat это нестандартный для GTA3 опкод, он добавляется через CLEO 2.0
https://github.com/cleolibrary/III.VC.C … .cpp#L1022
возможно, что он неправильно реализован, поэтому и выбивает ошибку
Offline
04A8: player $PLAYER_CHAR driving_boat это нестандартный для GTA3 опкод, он добавляется через CLEO 2.0
https://github.com/cleolibrary/III.VC.C … .cpp#L1022возможно, что он неправильно реализован, поэтому и выбивает ошибку
Спасибо это исправлено. Мне сейчас нужна помощь по адресам памяти и функциям.
Я пытаюсь заставить полицейскую лодку гоняющуюся стрелять пулями (просто плывет за игроком и должна стрелять пулями постепенно нанося урон). В начале кода была выделена память и смещение, также чуть в других местах и метке randcar прописано обновление координат. Функция стрельбы используется для гта 3 версии 1.1
Помогите мне пожалуйста чтобы лодка могла стрелять, а то она этого не делает совсем. Код прикреплен ниже, если будут вопросы пишите (да хоть в лс).
Offline
Pages: 1