#1 02-06-2007 12:49

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

Запись случайного актера / машины / объекта в переменную

Код для записи случайного актера / машины / объекта в переменную.

Изначально был написан PLPynton'ом, исправлен и улучшен мной.

Код принимает 4 параметра для поиска: координаты XYZ места, откуда начинать поиск, и радиус поиска.
Если в данном радиусе есть любой прохожий, машина или объект (это особенно прикольно, можно получить управление например над фонарным столбом smile), код записывает в переменную 9@ его хендл (который может использоваться в других опкодах). Если никого нет - возвращается -1.
Код игнорирует игрока и его машину.

При циклическом поиске, можно делать что-то вроде "искать следующего". Для этого в переменную 21@ нужно записать хендл предыдущего найденного актера / машины / объекта и при следующем поиске они будет пропущены. (для этого нужно раскомментировать участок кода в блоке AIC_NEWSEARCHRADIUS.

Работает только на версии 1.0

-------------------------

Код легко переносится на SAMB, нужно поменять только метки и тип aDMA (& -> $).

{
    The Interceptor
       
    by PLPynton and Seemann    

    Parameters:
    0@ - input coord X
    1@ - input coord Y
    2@ - input coord Z
    3@ - search radius

    variables 4@..20@ in use
    
    9@ = Result (returns -1 if not found)
           
}
:AIC_GETACTOR
0006: 16@ = 305868
0006: 17@ = @AIC_TESTACTORHANDLE
0006: 20@ = 1988
0002: jump @AIC_STARTSEARCH 

:AIC_GETVEHICLE
0006: 16@ = 305869
0006: 17@ = @AIC_TESTVEHICLEHANDLE
0006: 18@ = -1
0006: 20@ = 2584
0256:   player $PLAYER_CHAR defined
004D: jump_if_false @AIC_STARTSEARCH 
00DF:   actor $PLAYER_ACTOR driving
004D: jump_if_false @AIC_STARTSEARCH
03C0: 18@ = actor $PLAYER_ACTOR car
0002: jump @AIC_STARTSEARCH

:AIC_GETOBJECT
0006: 16@ = 305871
0006: 17@ = @AIC_TESTOBJECTHANDLE
0006: 20@ = 412

:AIC_STARTSEARCH 
0085: 4@ = 16@ // (int)
008B: 4@ = &0(4@,1i) // (int) 
0085: 19@ = 4@ // (int)
000E: 19@ -= 10787160
0016: 19@ /= 4 
008B: 19@ = &0(19@,1i) // (int)
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 4@ = &0(4@,1i) // (int)
0006: 9@ = -1 
0085: 11@ = 4@ // (int) 
0006: 10@ = 0

:AIC_SEARCHLOOPMAIN
000A: 4@ += 20 
0050: gosub @AIC_READ4B 
0085: 4@ = 5@ // (int) 
8039:   not  4@ == 0 
004D: jump_if_false @AIC_SEARCHLOOPNEXT 
000A: 4@ += 48 
0050: gosub @AIC_READ4B 
0085: 12@ = 5@ // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 13@ = 5@ // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 14@ = 5@ // (int) 
050A: 15@ = distance_between_XYZ 0@ 1@ 2@ and_XYZ 12@ 13@ 14@ 
0025:   3@ > 15@ // (float) 
004D: jump_if_false @AIC_SEARCHLOOPNEXT 
0085: 9@ = 10@ // (int) 
0085: 4@ = 16@ // (int) 
008B: 4@ = &0(4@,1i) // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 4@ = 5@ // (int) 
005A: 4@ += 9@ // (int) 
0050: gosub @AIC_READ1B 
0012: 9@ *= 256 
005A: 9@ += 5@ // (int)
0002: jump 17@

:AIC_TESTVEHICLEHANDLE
056E:   is 9@ valid_vehicle_handle
004D: jump_if_false @AIC_NOHANDLE
00D6: if or
003B:   18@ == 9@ // (int) 
0119:   car 9@ wrecked 
004D: jump_if_false @AIC_NEWSEARCHRADIUS
0002: jump @AIC_NOHANDLE

:AIC_TESTACTORHANDLE
056D:   is 9@ valid_actor_handle
004D: jump_if_false @AIC_NOHANDLE 
00D6: if or
003C:   $PLAYER_ACTOR == 9@ // (int) 
0118:   actor 9@ dead 
004D: jump_if_false @AIC_NEWSEARCHRADIUS
0002: jump @AIC_NOHANDLE

:AIC_TESTOBJECTHANDLE
//0001: wait 0
83CA:   not object 9@ exists 
004D: jump_if_false @AIC_NEWSEARCHRADIUS

:AIC_NOHANDLE
0006: 9@ = -1 
0002: jump @AIC_SEARCHLOOPNEXT 

:AIC_NEWSEARCHRADIUS
{  
   use 0051: return to break the loop
   immediately when found at least one actor/car/object, 
   does not matter if he's nearest one. 
}

// v EXTRA SEARCH CRITERIA GOES HERE v

{
  21@ contains the handle of an actor/car/object 
  that should be excluded from the search result 
  (for example a handle found previously). 
}
//803B:   21@ <> 9@
//004D: jump_if_false @AIC_NOHANDLE 

    
0085: 3@ = 15@ 

:AIC_SEARCHLOOPNEXT 
005A: 11@ += 20@ // (int) 
0085: 4@ = 11@ // (int) 
000A: 10@ += 1 
002D:   10@ >= 19@ // (int)
004D: jump_if_false @AIC_SEARCHLOOPMAIN
0051: return 

// ---------------------------------
:AIC_READ1B
0085: 6@ = 4@ // (int) 
0085: 8@ = 4@ // (int) 
0016: 4@ /= 4 
0012: 4@ *= 4 
0062: 8@ -= 4@ // (int) 
0012: 8@ *= 8 
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 7@ = &0(4@,1i) // (int) 
0085: 4@ = 6@ // (int) 
0006: 5@ = 0 
0006: 6@ = 0 

:AIC_READ1B_LOOP
08B9:   test 7@ bit 8@ 
004D: jump_if_false @AIC_READ1B_NEXTBIT 
08BF: set 5@ bit 6@ 

:AIC_READ1B_NEXTBIT
000A: 6@ += 1 
000A: 8@ += 1 
0039:   6@ == 8 
004D: jump_if_false @AIC_READ1B_LOOP 
0051: return 

:AIC_READ4B
0085: 6@ = 4@ // (int) 
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 5@ = &0(4@,1i) // (int) 
0085: 4@ = 6@ // (int) 
0051: return

-------------------------

Пример использования:

while true
   wait 100
        00A0: store_actor $PLAYER_ACTOR position_to 0@ 1@ 2@
        3@ = 20.0
        
        gosub @AIC_GETOBJECT
        if
                9@ <> -1
        then
                Marker.Disable($m2)
                Marker.CreateAboveObject($m2, 9@)
                wait 1000
                Object.Destroy(9@)
        end      
end

Скриншот:
Маркер над фонарным столбом, через несколько мгновений столб исчезнет...
t719339_mf.JPG

Offline

#2 03-06-2007 06:54

flashTrash
From: Н.Новгород
Registered: 21-02-2007
Posts: 260
Website

Re: Запись случайного актера / машины / объекта в переменную

А для чего это можно использовать, напрмер?

Offline

#3 03-06-2007 11:24

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

Re: Запись случайного актера / машины / объекта в переменную

Ну, например, можно проверять, проезжает ли рядом с игроком такси, если да - можно посадить игрока в него и запустить скрипт выбора маршрута...

На форумах часто спрашивают как записать актера/машину в переменную. Это - альтернатива стандартным опкодам, которые часто глючат.

Offline

#4 04-06-2007 05:33

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Seemann, а при помощи этой штуки можно заставить произвольного педа in group к CJ?
И еще.
Я просто поставила у себя приведенный тобой код и игрушка не запускается. Как правильно его ставить?
Я его прописала как create_thread @AIC_GETACTOR. Начала скрипт со строчек:

:AIC_GETACTOR
0006: 16@ = 305868
0006: 17@ = @AIC_TESTACTORHANDLE
0006: 20@ = 1988
0002: jump @AIC_STARTSEARCH

Offline

#5 04-06-2007 08:28

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

Re: Запись случайного актера / машины / объекта в переменную

В примере же написано: gosub @AIC_

а при помощи этой штуки можно заставить произвольного педа in group к CJ?

c актером можно делать что угодно.

Offline

#6 04-06-2007 08:46

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Seemann, для приведенного тобой примера применения кода нужно весь код прописывать в мейн? Или только ту часть, которая касается объекта? Т.е. :
:AIC_GETOBJECT
0006: 16@ = 305871
0006: 17@ = @AIC_TESTOBJECTHANDLE
0006: 20@ = 412
и т.д.

Offline

#7 04-06-2007 08:55

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

И что вот это за команда? :
:AIC_SEARCHLOOPMAIN
000A: 4@ += 20
0050: gosub @AIC_READ4B
0085: 4@ = 5@ // (int)
...
005A: 9@ += 5@ // (int)
0002: jump 17@ < так и должно быть?

Offline

#8 04-06-2007 09:40

yelmi
Registered: 10-12-2006
Posts: 134
Website

Re: Запись случайного актера / машины / объекта в переменную

0002: jump 17@ < так и должно быть?

0006: 17@ = @AIC_TESTOBJECTHANDLE

Offline

#9 04-06-2007 09:40

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

Re: Запись случайного актера / машины / объекта в переменную

для приведенного тобой примера применения кода нужно весь код прописывать в мейн? Или только ту часть, которая касается объекта?

Код универсальный, рассчитан на поиск как актеров, так и машин или объектов.
Но если тебе не нужны эти заморочки, ты можешь оставить только часть касающуюся например актеров. Тогда нужно убрать блок AIC_GETVEHICLE и AIC_GETOBJECT а также соответствующие блоки AIC_TEXTHANDLE.

jump 17@ - да, так и должно быть (причина выше).

Offline

#10 04-06-2007 09:57

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Вобщем я сделала вот так:

вписала после create_thread @TRI > create_thread @AIC_GETACTOR

затем над строчкой //-------------Mission 0--------------- вписала код

:AIC_GETACTOR
0006: 16@ = 305868
0006: 17@ = @AIC_TESTACTORHANDLE
0006: 20@ = 1988
0002: jump @AIC_STARTSEARCH 

:AIC_STARTSEARCH 
0085: 4@ = 16@ // (int)
008B: 4@ = &0(4@,1i) // (int) 
0085: 19@ = 4@ // (int)
000E: 19@ -= 10787160
0016: 19@ /= 4 
008B: 19@ = &0(19@,1i) // (int)
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 4@ = &0(4@,1i) // (int)
0006: 9@ = -1 
0085: 11@ = 4@ // (int) 
0006: 10@ = 0

:AIC_SEARCHLOOPMAIN
000A: 4@ += 20 
0050: gosub @AIC_READ4B 
0085: 4@ = 5@ // (int) 
8039:   not  4@ == 0 
004D: jump_if_false @AIC_SEARCHLOOPNEXT 
000A: 4@ += 48 
0050: gosub @AIC_READ4B 
0085: 12@ = 5@ // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 13@ = 5@ // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 14@ = 5@ // (int) 
050A: 15@ = distance_between_XYZ 0@ 1@ 2@ and_XYZ 12@ 13@ 14@ 
0025:   3@ > 15@ // (float) 
004D: jump_if_false @AIC_SEARCHLOOPNEXT 
0085: 9@ = 10@ // (int) 
0085: 4@ = 16@ // (int) 
008B: 4@ = &0(4@,1i) // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 4@ = 5@ // (int) 
005A: 4@ += 9@ // (int) 
0050: gosub @AIC_READ1B 
0012: 9@ *= 256 
005A: 9@ += 5@ // (int)
0002: jump 17@

:AIC_TESTACTORHANDLE
056D:   is 9@ valid_actor_handle
004D: jump_if_false @AIC_NOHANDLE 
00D6: if or
003C:   $PLAYER_ACTOR == 9@ // (int) 
0118:   actor 9@ dead 
004D: jump_if_false @AIC_NEWSEARCHRADIUS
0002: jump @AIC_NOHANDLE

:AIC_NOHANDLE
0006: 9@ = -1 
0002: jump @AIC_SEARCHLOOPNEXT 

:AIC_NEWSEARCHRADIUS
0085: 3@ = 15@ 

:AIC_SEARCHLOOPNEXT 
005A: 11@ += 20@ // (int) 
0085: 4@ = 11@ // (int) 
000A: 10@ += 1 
002D:   10@ >= 19@ // (int)
004D: jump_if_false @AIC_SEARCHLOOPMAIN
0051: return 

:AIC_READ1B
0085: 6@ = 4@ // (int) 
0085: 8@ = 4@ // (int) 
0016: 4@ /= 4 
0012: 4@ *= 4 
0062: 8@ -= 4@ // (int) 
0012: 8@ *= 8 
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 7@ = &0(4@,1i) // (int) 
0085: 4@ = 6@ // (int) 
0006: 5@ = 0 
0006: 6@ = 0 

:AIC_READ4B
0085: 6@ = 4@ // (int) 
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 5@ = &0(4@,1i) // (int) 
0085: 4@ = 6@ // (int) 
0051: return

Игра не запускается. Может я чего-то в упор не понимаю smile
Подскажите мне.

Offline

#11 04-06-2007 10:10

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

Re: Запись случайного актера / машины / объекта в переменную

Нельзя использовать этот код как поток.

Напиши поток с циклом, а в нем gosub @AIC_GETACTOR

Offline

#12 04-06-2007 10:29

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Ура! Заработало smile
Буду разбираться.

Offline

#13 04-06-2007 10:51

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Всё. Ум - закончился smile
А как же мне теперь заставить произвольного педа in_group?
Я попробовала тупо переделать код, но игра не думает запускать.

:AIC
thread 'AIC'
while true
   wait 100
        00A0: store_actor $PLAYER_ACTOR position_to 0@ 1@ 2@
        3@ = 20.0
        
        gosub @AIC_GETACTOR
        if
                9@ <> -1
        then
                Marker.Disable($m2)
                Marker.CreateAboveActor($m2, 9@)
                wait 1000
                0631: put_actor 9@ in_group $PLAYER_GROUP
        end      
end

Last edited by svetka (04-06-2007 11:04)

Offline

#14 04-06-2007 11:07

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Я сначала не на тот gosub отправила. Теперь исправила и при приближении к педу игра вистнет.  И как писать скрипт для выбора педа? Я что-то принцип никак не пойму:/

Last edited by svetka (04-06-2007 11:21)

Offline

#15 04-06-2007 12:26

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Спасибо, Seemann, за молчание.
Я разобралась smile

Offline

#16 04-06-2007 13:31

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

Re: Запись случайного актера / машины / объекта в переменную

Вот и отлично. Еще разберись с кнопкой "Редактировать", ок? wink

Offline

#17 04-06-2007 13:32

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

CJ собирает всех педов подряд. Можно ли сделать включение и отключение кода? Я пробовала через нажатие клавишь это осуществить - ингра вылетает.
Как сделать, чтобы можно было набирать нужное количество педов?

Offline

#18 04-06-2007 13:33

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Вот и отлично. Еще разберись с кнопкой "Редактировать", ок?

В смысле? hmm

Offline

#19 04-06-2007 13:45

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

Re: Запись случайного актера / машины / объекта в переменную

CJ собирает всех педов подряд.

при каждом добавлении актера в группу увеличивай свой счетчик или проверяй число членов в группе. если оно равно максимальному - тогда не делай добавления.

В смысле?

не надо писать по 2-4 поста подряд, можно редактировать предыдущие.

Offline

#20 04-06-2007 13:59

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Seemann, как же я могу не добавлять в группу новых педов, если они сами ко мне бегут? Автоматически. Даже из машин вылазят smile
Как ограничить их количество?

Offline

#21 04-06-2007 14:01

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

Re: Запись случайного актера / машины / объекта в переменную

Выложи код, что ли.

Offline

#22 04-06-2007 14:14

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

Вот код. Переделала из твоего.

:NONAME_13
while true
   wait 100
        00A0: store_actor $PLAYER_ACTOR position_to 0@ 1@ 2@
        3@ = 20.0
        
        gosub @AIC_GETACTOR
        if
                9@ <> -1
        then
                Marker.Disable($m2)
                Marker.CreateAboveActor($m2, 9@)
                wait 1000
                0631: put_actor 9@ in_group $PLAYER_GROUP
        end      
end

:AIC_GETACTOR
0006: 16@ = 305868
0006: 17@ = @AIC_TESTACTORHANDLE
0006: 20@ = 1988
0002: jump @AIC_STARTSEARCH 

:AIC_STARTSEARCH 
0085: 4@ = 16@ // (int)
008B: 4@ = &0(4@,1i) // (int) 
0085: 19@ = 4@ // (int)
000E: 19@ -= 10787160
0016: 19@ /= 4 
008B: 19@ = &0(19@,1i) // (int)
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 4@ = &0(4@,1i) // (int)
0006: 9@ = -1 
0085: 11@ = 4@ // (int) 
0006: 10@ = 0

:AIC_SEARCHLOOPMAIN
000A: 4@ += 20 
0050: gosub @AIC_READ4B 
0085: 4@ = 5@ // (int) 
8039:   not  4@ == 0 
004D: jump_if_false @AIC_SEARCHLOOPNEXT 
000A: 4@ += 48 
0050: gosub @AIC_READ4B 
0085: 12@ = 5@ // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 13@ = 5@ // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 14@ = 5@ // (int) 
050A: 15@ = distance_between_XYZ 0@ 1@ 2@ and_XYZ 12@ 13@ 14@ 
0025:   3@ > 15@ // (float) 
004D: jump_if_false @AIC_SEARCHLOOPNEXT 
0085: 9@ = 10@ // (int) 
0085: 4@ = 16@ // (int) 
008B: 4@ = &0(4@,1i) // (int) 
000A: 4@ += 4 
0050: gosub @AIC_READ4B 
0085: 4@ = 5@ // (int) 
005A: 4@ += 9@ // (int) 
0050: gosub @AIC_READ1B 
0012: 9@ *= 256 
005A: 9@ += 5@ // (int)
0002: jump 17@

:AIC_TESTACTORHANDLE
056D:   is 9@ valid_actor_handle
004D: jump_if_false @AIC_NOHANDLE 
00D6: if or
003C:   $PLAYER_ACTOR == 9@ // (int) 
0118:   actor 9@ dead 
004D: jump_if_false @AIC_NEWSEARCHRADIUS
0002: jump @AIC_NOHANDLE

:AIC_NOHANDLE
0006: 9@ = -1 
0002: jump @AIC_SEARCHLOOPNEXT 

:AIC_NEWSEARCHRADIUS    
0085: 3@ = 15@ 

:AIC_SEARCHLOOPNEXT 
005A: 11@ += 20@ // (int) 
0085: 4@ = 11@ // (int) 
000A: 10@ += 1 
002D:   10@ >= 19@ // (int)
004D: jump_if_false @AIC_SEARCHLOOPMAIN
0051: return 

:AIC_READ1B
0085: 6@ = 4@ // (int) 
0085: 8@ = 4@ // (int) 
0016: 4@ /= 4 
0012: 4@ *= 4 
0062: 8@ -= 4@ // (int) 
0012: 8@ *= 8 
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 7@ = &0(4@,1i) // (int) 
0085: 4@ = 6@ // (int) 
0006: 5@ = 0 
0006: 6@ = 0 

:AIC_READ1B_LOOP
08B9:   test 7@ bit 8@ 
004D: jump_if_false @AIC_READ1B_NEXTBIT 
08BF: set 5@ bit 6@ 

:AIC_READ1B_NEXTBIT
000A: 6@ += 1 
000A: 8@ += 1 
0039:   6@ == 8 
004D: jump_if_false @AIC_READ1B_LOOP 
0051: return 

:AIC_READ4B
0085: 6@ = 4@ // (int) 
000E: 4@ -= 10787168 
0016: 4@ /= 4 
008B: 5@ = &0(4@,1i) // (int) 
0085: 4@ = 6@ // (int) 
0051: return

Могу выложить скомпилированный, если надо.

Offline

#23 04-06-2007 15:31

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

Re: Запись случайного актера / машины / объекта в переменную

2svetka:
читаем еще раз

при каждом добавлении актера в группу увеличивай свой счетчик или проверяй число членов в группе. если оно равно максимальному - тогда не делай добавления

Offline

#24 04-06-2007 16:28

svetka
Registered: 29-12-2006
Posts: 222

Re: Запись случайного актера / машины / объекта в переменную

2Seemann:

увеличивай свой счетчик

Где в коде счетчик? И где отображено число членов в группе? Извини, но я не настолько продвинутая smile

Offline

#25 04-06-2007 17:15

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

Re: Запись случайного актера / машины / объекта в переменную

Где в коде счетчик?

свой счетчик

это значит надо его добавить.

И где отображено число членов в группе?

07F6: get_group 260@ number_of_leaders_to 262@ number_of_members_to 261@

Offline

Board footer

Powered by FluxBB