#1 03-12-2020 09:41

Remca12
Registered: 30-06-2019
Posts: 32

Проблемы со скриптом

Здравствуйте. Я пишу скрипт подрывника. Суть: в игре есть 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

#2 03-12-2020 14:51

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Проблемы со скриптом

Для начала нужно избавиться от всех глобальных переменных, кроме $PLAYER_ACTOR.
Переменную $flag_player_on_mission заменить на $onmission

end_thread заменить на 0A93: terminate_this_custom_script

Offline

#3 03-12-2020 16:53

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Спасибо, но это всё сразу в 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

#4 04-12-2020 07:12

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Проблемы со скриптом

это всё сразу в main.scm-е пишется

не совсем очевидно из вашего примера, в котором есть директива {$CLEO}, ну да ладно. Из того что бросилось в глаза, подрывник создается с типом 18. В GTA 3 для создания скриптовых персонажей в основном используется тип 21 (Special). Попробуйте с этим типом, может поведение будет иное.

Offline

#5 04-12-2020 09:10

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Спасибо за пояснения,  подрывник себя должен подрывать пока он жив и игрок жив, но если хоть кто-то из них умрёт, то подрывник больше не будет нужен.
Осталась лишь самая странная проблема: подрывник себя подрывает только 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

#6 04-12-2020 14:44

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Проблемы со скриптом

Тип актера задается при создании
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

#7 04-12-2020 15:50

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Спасибо за  типы, возьму на заметку)
Я убирал break, но при первом же подрывании себя подрывник сдох, а затем я закомментировал строку где снимается иммунитет подрывника от взрыва, но тогда он себя подрывает кучу раз стоя на одном месте. А подрывник должен подрываться  если игрок близко с подрывником, но если подрывник ещё жив, то он опять должен побежать к игроку чтобы подорваться до тех пор пока он сам не умрет.
Если цикл не прерывать то за подрывником будет хвост взрывов пока он бежит, а он не побежит если к нему не подойти. Но если цикл прерывать то он себя подорвет лишь 1 раз.

Last edited by Remca12 (04-12-2020 16:42)

Offline

#8 04-12-2020 20:10

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Проблемы со скриптом

но тогда он себя подрывает кучу раз стоя на одном месте

а кто ему говорит, что нужно бежать? По условию взрыв происходит если подрывник находится рядом с игроком. Если игрок стоит на месте, что должно произойти? Подрывник ведь тоже будет стоять? Наверно, есть смысл переместить взрыв (опкод 020C) после проверки 02A0:   actor $BOMBER stopped.

Т.е. логика должна быть примерно такая

создали подрывника
запускаем бесконечный цикл (while true)

проверяем, если игрок или подрывник умер - делаем break
проверяем остановился ли подрывник рядом с игроком
если да, то создаем explosion
если нет, заставляем его бежать
делаем паузу на 2 секунды (тогда серия взрывов будет реже)

конец цикла

очистка

Offline

#9 05-12-2020 08:14

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Измененный код подрывника. Я не останавливаю игрока, так как это мешает ему кидать гранаты, вместо этого я его заставляю посмотреть в сторону игрока.

Last edited by Remca12 (05-12-2020 09:30)

Offline

#10 05-12-2020 09:27

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Код обновлён. Вроде как всё верно. Если что-то неверно - слушаю.

Last edited by Remca12 (05-12-2020 09:29)

Offline

#11 07-12-2020 16:59

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Seemann wrote:

но тогда он себя подрывает кучу раз стоя на одном месте

а кто ему говорит, что нужно бежать? По условию взрыв происходит если подрывник находится рядом с игроком. Если игрок стоит на месте, что должно произойти? Подрывник ведь тоже будет стоять? Наверно, есть смысл переместить взрыв (опкод 020C) после проверки 02A0:   actor $BOMBER stopped.

Т.е. логика должна быть примерно такая

создали подрывника
запускаем бесконечный цикл (while true)

проверяем, если игрок или подрывник умер - делаем break
проверяем остановился ли подрывник рядом с игроком
если да, то создаем explosion
если нет, заставляем его бежать
делаем паузу на 2 секунды (тогда серия взрывов будет реже)

конец цикла

очистка

Как проверить что игрок на каком-то острове ? Я пытаюсь телепортировать актёра на тот же остров на котором находится игрок опкодом 03fc ? Но он не условный, а других способов я не знаю. Гта 3, если что.

Offline

#12 08-12-2020 00:59

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Проблемы со скриптом

03C6:   current_island == 1

Offline

#13 11-12-2020 05:36

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Seemann wrote:

03C6:   current_island == 1

Пока я тестировал скрипт, вышла интересная проблема: если игрок собрал спрятанный пакет на одном острове и переместился на другой остров, неважно как (додо, noclip и т.д.), то актер будет телепортироваться. Но находится он будет в земле, а не на путях педов и машин. Код тот же самый. (пока не измененный)

Offline

#14 13-12-2020 09:46

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Помогите пожалуйста. Я пытаюсь создавать случайную лодку, но пока гта 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

#15 13-12-2020 21:12

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Проблемы со скриптом

04A8: player $PLAYER_CHAR driving_boat это нестандартный для GTA3 опкод, он добавляется через CLEO 2.0
https://github.com/cleolibrary/III.VC.C … .cpp#L1022

возможно, что он неправильно реализован, поэтому и выбивает ошибку

Offline

#16 18-12-2020 07:51

Remca12
Registered: 30-06-2019
Posts: 32

Re: Проблемы со скриптом

Seemann wrote:

04A8: player $PLAYER_CHAR driving_boat это нестандартный для GTA3 опкод, он добавляется через CLEO 2.0
https://github.com/cleolibrary/III.VC.C … .cpp#L1022

возможно, что он неправильно реализован, поэтому и выбивает ошибку

Спасибо это исправлено. Мне сейчас нужна помощь по адресам памяти и функциям.

Я пытаюсь заставить полицейскую лодку гоняющуюся стрелять пулями (просто плывет за игроком и должна стрелять пулями постепенно нанося урон). В начале кода была выделена память и смещение, также чуть в других местах и метке randcar прописано обновление координат. Функция стрельбы используется для гта 3 версии 1.1
Помогите мне пожалуйста чтобы лодка могла стрелять, а то она этого не делает совсем. Код прикреплен ниже, если будут вопросы пишите (да хоть в лс).

Offline

Board footer

Powered by FluxBB