You are not logged in.
Код для записи случайного актера / машины / объекта в переменную.
Изначально был написан PLPynton'ом, исправлен и улучшен мной.
Код принимает 4 параметра для поиска: координаты XYZ места, откуда начинать поиск, и радиус поиска.
Если в данном радиусе есть любой прохожий, машина или объект (это особенно прикольно, можно получить управление например над фонарным столбом
), код записывает в переменную 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Скриншот:
Маркер над фонарным столбом, через несколько мгновений столб исчезнет...
Offline
А для чего это можно использовать, напрмер?
Offline
Ну, например, можно проверять, проезжает ли рядом с игроком такси, если да - можно посадить игрока в него и запустить скрипт выбора маршрута...
На форумах часто спрашивают как записать актера/машину в переменную. Это - альтернатива стандартным опкодам, которые часто глючат.
Offline
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
В примере же написано: gosub @AIC_
а при помощи этой штуки можно заставить произвольного педа in group к CJ?
c актером можно делать что угодно.
Offline
Seemann, для приведенного тобой примера применения кода нужно весь код прописывать в мейн? Или только ту часть, которая касается объекта? Т.е. :
:AIC_GETOBJECT
0006: 16@ = 305871
0006: 17@ = @AIC_TESTOBJECTHANDLE
0006: 20@ = 412
и т.д.
Offline
И что вот это за команда? :
:AIC_SEARCHLOOPMAIN
000A: 4@ += 20
0050: gosub @AIC_READ4B
0085: 4@ = 5@ // (int)
...
005A: 9@ += 5@ // (int)
0002: jump 17@ < так и должно быть?
Offline
для приведенного тобой примера применения кода нужно весь код прописывать в мейн? Или только ту часть, которая касается объекта?
Код универсальный, рассчитан на поиск как актеров, так и машин или объектов.
Но если тебе не нужны эти заморочки, ты можешь оставить только часть касающуюся например актеров. Тогда нужно убрать блок AIC_GETVEHICLE и AIC_GETOBJECT а также соответствующие блоки AIC_TEXTHANDLE.
jump 17@ - да, так и должно быть (причина выше).
Offline
Вобщем я сделала вот так:
вписала после 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
Игра не запускается. Может я чего-то в упор не понимаю
Подскажите мне.
Offline
Нельзя использовать этот код как поток.
Напиши поток с циклом, а в нем gosub @AIC_GETACTOR
Offline
Ура! Заработало 
Буду разбираться.
Offline
Всё. Ум - закончился 
А как же мне теперь заставить произвольного педа 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
Я сначала не на тот gosub отправила. Теперь исправила и при приближении к педу игра вистнет. И как писать скрипт для выбора педа? Я что-то принцип никак не пойму:/
Last edited by svetka (04-06-2007 11:21)
Offline
Спасибо, Seemann, за молчание.
Я разобралась 
Offline
Вот и отлично. Еще разберись с кнопкой "Редактировать", ок? 
Offline
CJ собирает всех педов подряд. Можно ли сделать включение и отключение кода? Я пробовала через нажатие клавишь это осуществить - ингра вылетает.
Как сделать, чтобы можно было набирать нужное количество педов?
Offline
Вот и отлично. Еще разберись с кнопкой "Редактировать", ок?
В смысле? 
Offline
CJ собирает всех педов подряд.
при каждом добавлении актера в группу увеличивай свой счетчик или проверяй число членов в группе. если оно равно максимальному - тогда не делай добавления.
В смысле?
не надо писать по 2-4 поста подряд, можно редактировать предыдущие.
Offline
Seemann, как же я могу не добавлять в группу новых педов, если они сами ко мне бегут? Автоматически. Даже из машин вылазят
Как ограничить их количество?
Offline
Выложи код, что ли.
Offline
Вот код. Переделала из твоего.
: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
2svetka:
читаем еще раз
при каждом добавлении актера в группу увеличивай свой счетчик или проверяй число членов в группе. если оно равно максимальному - тогда не делай добавления
Offline
2Seemann:
увеличивай свой счетчик
Где в коде счетчик? И где отображено число членов в группе? Извини, но я не настолько продвинутая 
Offline
Где в коде счетчик?
свой счетчик
это значит надо его добавить.
И где отображено число членов в группе?
07F6: get_group 260@ number_of_leaders_to 262@ number_of_members_to 261@
Offline