[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 11
Форум » Игры серии GTA » GTA San Andreas » Задача о 5ти актёрах.
Задача о 5ти актёрах.
DK22Pac
Друзья
TOP Скриптер
30.12.13 03:47
Offline
Собственно,
Цитата
Если ваш друг постоянно говорит вам о своём великолепном умении писать CLEO-скрипты, попросите его решить (или точнее - написать) следующий, очень простой скрипт:
1) Создайте 5 актёров;
2) Для каждого из созданных актёров, выполните следующие действия (параллельно для каждого из актёров): стоит; приседает; получает оружие; атакует игрока, - при этом, задержки между этими задачами для каждого из актёров должны быть рандомными (опкод 0099 в помощь. Допустим, актёр #1 стоит на месте 2134 мс, затем приседает и ждёт 5421 мс, затем получает оружие и ждёт 2211 мс, и затем атакует игрока.

После того, как ваш друг ничего не сможет вам предложить, скажите ему, что для того, чтобы писать качественные скрипты, мало прочитать несколько справочных статей по скриптингу...

wmysterio
Администраторы
Скриптер
30.12.13 04:12
Offline
Цитата DK22Pac ()
После того, как ваш друг ничего не сможет вам предложить, скажите ему, что для того, чтобы писать качественные скрипты, мало прочитать несколько справочных статей по скриптингу...
С этим не поспоришь smile
if( robots->EvilFlag = true ) {
robots->KillHumans();
}

alfazlo
Пользователи
30.12.13 22:48
Offline
дайте мне готовый код если у кого есть в лс а то я перемудриваю походу сильно
вот что вышло в кратце
Код

0376: 1@ = create_random_actor_at 0.0 0.0 0.0   
0376: 2@ = create_random_actor_at 1.0 0.0 0.0   
0376: 3@ = create_random_actor_at 2.0 0.0 0.0   
0376: 4@ = create_random_actor_at 3.0 0.0 0.0   
0376: 5@ = create_random_actor_at 4.0 0.0 0.0   

0AC6: 7@ = label @random offset
for 30@ = 0 to 12
0099: 6@ = random_int_in_ranges 0 to 10000
0A8C: write_memory 7@ size 2 value 6@ virtual_protect 0
7@ += 2
end

while true
wait 0
0AC6: 8@ = label @state offset
32@ = 0   
0AC7: 0@ = var 1@ offset
6@ = 0@   
6@ += 20
0AC6: 7@ = label @random offset
for 30@ = 0@ to 6@ step 4
0A8D: 9@ = read_memory 8@ size 1 virtual_protect 0
if 9@ == 0   
then
0A8D: 10@ = read_memory 7@ size 2 virtual_protect 0
if 10@ >= 32@   
then
//äåéñòâèå
end
9@ += 1
0A8C: write_memory 8@ size 1 value 9@ virtual_protect 0
else if 9@ == 1
       then
       0A8D: 10@ = read_memory 7@ size 2 virtual_protect 0
       7@ += 2
       0A8D: 11@ = read_memory 7@ size 2 virtual_protect 0
       10@ += 11@
       if 10@ >= 32@   
       then
       //äåéñòâèå
       end
       9@ += 1
       0A8C: write_memory 8@ size 1 value 9@ virtual_protect 0
       else if 9@ == 2
            then
             0A8D: 10@ = read_memory 7@ size 2 virtual_protect 0
             7@ += 2
             0A8D: 11@ = read_memory 7@ size 2 virtual_protect 0
             10@ += 11@
             if 10@ >= 32@   
             then
             //äåéñòâèå
             end
            9@ += 1
            0A8C: write_memory 8@ size 1 value 9@ virtual_protect 0
            else if 9@ == 3
                 then   
                 0A8D: 10@ = read_memory 7@ size 2 virtual_protect 0
                 7@ += 2
                 0A8D: 11@ = read_memory 7@ size 2 virtual_protect 0
                 7@ += 2
                 0A8D: 12@ = read_memory 7@ size 2 virtual_protect 0
                 10@ += 11@
                 10@ += 12@
                 if 10@ >= 32@   
                 then
                 //äåéñòâèå
                 end
                 9@ += 1
                 0A8C: write_memory 8@ size 1 value 9@ virtual_protect 0
                 end
            end
       end

end      
8@ += 1
7@ += 6
end   
//
end

:random
hex
0000 0000 0000   
0000 0000 0000
0000 0000 0000   
0000 0000 0000
end

:state
hex
00 00 00 00 00   
end


сначала показалось все просто, потом показалось что без многопоточности не обойтись, а потом пришел бесконечный цикл с проверкой текущего состояния и измерением времени для каждого перса. Я так понимаю автор задачи ее решил и думаю там гораздо более упрощенный вариант чем перебирать цикл, да и тут либо точностью либо фп придется жертвовать один wait 0 у меня 100 мс съедает. Дайте готовый код, если в нем не используются отдельные потоки.
Отредактировал alfazlo - Вторник, 31.12.13, 00:00

BoPoH
Друзья
01.01.14 17:28
Offline
Цитата alfazlo ()
Я так понимаю автор задачи ее решил и думаю там гораздо более упрощенный вариант чем перебирать цикл, да и тут либо точностью либо фп придется жертвовать один wait 0 у меня 100 мс съедает

Нет. Эта задача решается именно циклом, а не многопоточностью. Потери из-за wait 0 неизбежны, так что это не считается. Естественно для решения этой задачи нужно использовать не wait'ы, как кажется на первый взгляд, а с помощью переменных-таймеров (32@ и 33@). Ты вроде использовал именно этот подход, но код у тебя как-то очень стрёмно оформлен, сложно читать. Да и, может мне кажется, но обнуление переменной 32@ должно быть перед циклом. А то ты каждый цикл её обнуляешь и сразу сверяешь с рандомными значениями. Конечно проверка не сработает никогда.
Вообще я думаю, эту задачу вполне реально решить и без применения работы с памятью.

Добавлено (01.01.14, 16:28)
---------------------------------------------
Да, кстати, DK22Pac, ты ошибочно (а может нарочно) указал на необходимость использования опкода 0099, хотя он предназначен для использования с глобальными переменными.
Вобщем вот мой вариант решения:
Код
var
1@: array 5 of Integer
6@: array 5 of Integer
11@: array 5 of Integer
end

model.Load(#MICRO_UZI)
038B: load_requested_models

24@ = -4.0
for 0@ = 0 to 4
       04C4: store_coords_to 21@ 22@ 23@ from_actor $PLAYER_ACTOR with_offset 24@ 3.0 0.0 // Создаём актёров перед игроком
       0376: 1@[0@] = create_random_actor_at 21@ 22@ 23@
       24@ += 2.0
          
       6@[0@] = 0 // Обнуляем индекс действия
       0209: 11@[0@] = random_int_in_ranges 0 10000 // Создаём рандомные временные отрезки для первого действия
end

33@ = 0 // Обнуляем таймер
while true
wait 0
       for 0@ = 0 to 4     // В цикле выполняем проверки для каждого актёра
           if
           002D:   33@ >= 11@[0@]  // Проверяем, пришло ли время очередного действия
           then
               if
               6@[0@] < 3    // И если актёр ещё не выполнил все действия
               then
                   0209: 30@ = random_int_in_ranges 0 10000     // Если да, то прибавляем очередное рандомное значение
                   005A: 11@[0@] += 30@
                   gosub @doAction     // И заставляем актёра делать действие, соответствующее индексу действия
               end
           end
       end
          
       if and      // Проверим, если все актёры закончили действия
       6@ >= 3
       7@ >= 3
       8@ >= 3
       9@ >= 3
       10@ >= 3
       then
           0A93: end_custom_thread    // Если да - завершаем работу скрипта
       end
end

:doAction // Действие "Стоять на месте" мы не делаем, т.к. актёры и без того уже стоят    
if
6@[0@] == 0       
then
       04EB: AS_actor 1@[0@] crouch 1
else
       if
       6@[0@] == 1
       then
           01B2: give_actor 1@[0@] weapon 28 ammo 9999
       else
           if
           6@[0@] == 2    
           then
               07A5: AS_actor 1@[0@] attack_actor $PLAYER_ACTOR time 999999
           else
               jump @Return    // Если все действия уже были проделаны актёром, то просто пропускаем его
           end
       end
end
6@[0@] += 1     // Если было задано очередное действие, прибавляем индекс действия

:Return
return
Отредактировал BoPoH - Среда, 01.01.14, 17:30

Форум » Игры серии GTA » GTA San Andreas » Задача о 5ти актёрах.
Страница 1 из 11
Поиск: