000133. Делаем диалоги в миссиях
Делаем диалоги в миссиях|Всем привет! В этом, неожиданном для меня уроке, речь пойдёт о диалогах и о том, как можно использовать их, например, в процессе выполнения миссии, где нужно приехать в какую-то точку, и при этом персонажи разговаривали между собой.|wmysterio|wmysterio||||Одним из способов является введение переменной-счётчика для цикла, и при выполнении условия с этим счётчиком мы выводим нужный нам текст. К этому же мы должны создать переменную-индекс, которая будет выводить текст по порядку. Для этого создадим в начале миссии транспорт и случайного актёра, после чего посадим их в транспорт:
1
Model.Load(#ADMIRAL)
2
038B: load_requested_models
3
[email protected] = car.Create(#ADMIRAL, 2495.6694, -1657.3169, 12.3608)
4
car.Angle([email protected]) = 89.0987
5
0229: set_car [email protected] primary_color_to 1 secondary_color_to 1
6
Model.Destroy(#ADMIRAL)
7
0560: create_random_actor_in_car [email protected] handle_as [email protected]
8
0430: put_actor [email protected] into_car [email protected] passenger_seat 0
9
072A: put_actor $PLAYER_ACTOR into_car [email protected] driverseat
Copied!
Дальше осветляем экран и вводим переменную-индекс и переменную-счётчик:
1
fade 1 1000
2
wait 1000
3
player.CanMove(0, 1)
4
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
5
[email protected] = 0 // index dialog
6
[email protected] = 0.0 // mini-timer dialog
Copied!
Теперь нужно создать цикл, который будет увеличивать счётчик на 0.25. Это более менее хорошмй вариант. Дальше осуществим перебор условий:
1
:MISSION_AA_LOOP
2
wait 0
3
if
5
then
6
jump @MISSION_AA_LOOP
7
end
8
9
if AND
12
then
13
0AD0: show_formatted_text_lowpriority "CJ: I drive car in point!" time 5000
16
end
17
18
if AND
21
then
22
0AD0: show_formatted_text_lowpriority "Friend: Ok. I sead down in this car!" time 5000
25
end
26
27
if AND
30
then
31
0AD0: show_formatted_text_lowpriority "CJ: This point in location Observatory!" time 5000
34
end
35
36
if AND
39
then
40
0AD0: show_formatted_text_lowpriority "Friend: I known. Is this car heavy?" time 5000
43
end
44
45
if AND
48
then
49
0AD0: show_formatted_text_lowpriority "CJ: No. Light." time 3000
52
end
53
54
if AND
57
then
58
0AD0: show_formatted_text_lowpriority "Friend: You drive very good!" time 5000
61
end
62
63
if AND
66
then
67
0AD0: show_formatted_text_lowpriority "CJd: Thank you! I drive vehicles very time" time 5000
70
end
71
73
jump @MISSION_AA_LOOP
Copied!
У нас будет 7 фраз, каждая из которых имеет индекс, начинающийся с нуля. Сделаем проверку, что если индекс больше 6-ти, то прыгаем на метку начала цикла. Как показала практика, так будет более-менее оптимально для производительности. Дальше уже следуют ряд условий, в которых определяется какой текст и когда нужно выводить. К примеру, "[email protected] == 3" - идёт проверка на индекс. Если текущий индекс равен 3, то проверяем счётчик: "[email protected] >= 45.0" - если он больше, чем заданное число, то выводим текст, прибавляем индексу единицу и сбиваем счётчик на ноль.
И так текст будет по очереди выводится, пока индекс будет в заданном диапазоне. Чем меньше число для проверки [email protected], тем быстрее выводится текст. В остановился на числе 45.0, так как оно хорошо подходит под время выводимого текста. Как я его получил? Просто:
  • Беру длительность предыдущего текста ( текста выше по коду ) - в нашем случае это 5000;
  • Делю его на 100, получаю 50. Отнимаю 5, получаю 45 и перевожу в дробное 45.0 - это примерно равно 5000 милисекундам ( ЭТО ЕСЛИ К [email protected] ПРИБАВЛЯТЬ 0.25, КАК НАПИСАНО В КОДЕ ВЫШЕ. ЕСЛИ ПОМЕНЯТЬ ЭТО ЗНАЧЕНИЕ, ТО ПРОВЕРКУ НУЖНО БУДЕТ ПОДСТРАИВАТЬ )
Хорошо, фразы выводится по очереди. Теперь напишем условия, когда миссия считается проваленной:
1
if OR
2
car.Wrecked([email protected])
3
02BF: car [email protected] sunk
4
then
5
jump @MISSION_29_144_END_CAR
6
end
7
if
8
actor.Dead([email protected])
9
then
10
jump @MISSION_29_144_END_ACT
11
end
Copied!
И создадим соответствующие метки:
1
:MISSION_29_144_END_CAR
2
wait 0
3
gosub @MISSION_END
4
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
5
0AD0: show_formatted_text_lowpriority "You car wrecked!" time 4000
6
return
7
8
:MISSION_29_144_END_ACT
9
wait 0
10
gosub @MISSION_END
11
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
12
0AD0: show_formatted_text_lowpriority "You Friend dai!" time 4000
13
return
Copied!
Теперь перед циклом добавим код, который будет говорить о том, куда ехать и создавать сферу и чекпоинт в нужном месте:
1
:MISSION_AA
2
wait 0
3
marker.Disable([email protected])
4
marker.Disable([email protected])
5
018A: [email protected] = create_checkpoint_at 1695.4817 -2107.7493 13.5469
6
03BC: [email protected] = create_sphere_at 1695.4817 -2107.7493 13.5469 radius 2.0
7
0AD0: show_formatted_text_lowpriority "Drive to point!" time 4000
Copied!
Добавим проверку, что когда игрок с актёром в этой точке, то завершить миссию и сообщить о успешном её выполнении:
1
:MISSION_AA_LOOP
2
wait 0
3
4
// ...
5
6
if AND
7
actor.InCar($PLAYER_ACTOR, [email protected])
9
00EC: actor $PLAYER_ACTOR sphere 0 near_point 1695.4817 -2107.7493 radius 2.0 2.0
10
then
11
jump @MISSION_CC
12
end
13
14
// ...
15
16
jump @MISSION_AA_LOOP
17
18
:MISSION_CC
19
marker.Disable([email protected])
20
03BD: destroy_sphere [email protected]
21
00BE: text_clear_all
22
player.CanMove(0, 0)
23
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
24
fade 0 1000
25
wait 1000
26
0633: AS_actor $PLAYER_ACTOR exit_car
27
28
while actor.InCar($PLAYER_ACTOR, [email protected])
29
wait 0
30
end
31
32
gosub @MISSION_END
33
actor.PutAt($PLAYER_ACTOR, 1698.6144, -2096.208, 12.5469)
34
actor.Angle($PLAYER_ACTOR) = 181.9148
35
camera.Restore_WithJumpCut
36
Camera.SetBehindPlayer
37
wait 500
38
fade 1 1000
39
wait 1000
40
player.CanMove(0, 1)
41
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
42
0394: play_music 1
43
00BA: show_text_styled GXT 'M_PASSR' time 5000 style 1 // MISSION PASSED
44
return
Copied!
Осталось добавить ещё одну вещь: организовать проверку на то, что актёр или игрок покинули транспорт. Я сделал это следующим образом:
1
:MISSION_AA_LOOP
2
wait 0
3
4
// ...
5
6
if OR
7
not actor.InCar($PLAYER_ACTOR, [email protected])
9
then
10
jump @MISSION_BB
11
end
12
13
// ...
14
15
jump @MISSION_AA_LOOP
16
17
:MISSION_BB
18
wait 0
19
marker.Disable([email protected])
20
03BD: destroy_sphere [email protected]
21
00BE: text_clear_all
22
[email protected] = marker.CreateAboveActor([email protected])
23
07E0: set_marker [email protected] type_to 1
24
[email protected] = marker.CreateAboveCar([email protected])
25
07E0: set_marker [email protected] type_to 1
26
0AD0: show_formatted_text_lowpriority "Hey, run in car!" time 4000
27
28
:MISSION_BB_LOOP
29
wait 0
30
if OR
31
car.Wrecked([email protected])
32
02BF: car [email protected] sunk
33
then
34
jump @MISSION_29_144_END_CAR
35
end
36
if
37
actor.Dead([email protected])
38
then
39
jump @MISSION_29_144_END_ACT
40
end
41
if AND
42
actor.InCar($PLAYER_ACTOR, [email protected])
44
then
45
jump @MISSION_AA
46
end
47
jump @MISSION_BB_LOOP
Copied!
Таким образом, диалог будет происходить только тогда, когда СЖ и этот случайный актёр будут в машине [email protected] Если соединить всё вместе, то получится следующий код:
1
{$CLEO .cm}
2
3
//------------- Mission ---------------
4
5
:MISSION
6
thread 'MISSION'
7
gosub @MISSION_29_57
8
if
9
wasted_or_busted
10
jf @MISSION_29_46
11
gosub @MISSION_29_144
12
13
:MISSION_29_46
14
$ONMISSION = 0
15
mission_cleanup
16
end_thread
17
18
:MISSION_29_57
19
increment_mission_attempts
20
$ONMISSION = 1
21
Model.Load(#ADMIRAL)
22
038B: load_requested_models
23
[email protected] = car.Create(#ADMIRAL, 2495.6694, -1657.3169, 12.3608)
24
car.Angle([email protected]) = 89.0987
25
0229: set_car [email protected] primary_color_to 1 secondary_color_to 1
26
Model.Destroy(#ADMIRAL)
27
0560: create_random_actor_in_car [email protected] handle_as [email protected]
28
0430: put_actor [email protected] into_car [email protected] passenger_seat 0
29
072A: put_actor $PLAYER_ACTOR into_car [email protected] driverseat
30
wait 1000
31
camera.Restore_WithJumpCut
32
Camera.SetBehindPlayer
33
fade 1 1000
34
wait 1000
35
player.CanMove(0, 1)
36
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
37
[email protected] = 0 // index dialog
38
[email protected] = 0.0 // mini-timer dialog
39
40
:MISSION_AA
41
wait 0
42
marker.Disable([email protected])
43
marker.Disable([email protected])
44
018A: [email protected] = create_checkpoint_at 1695.4817 -2107.7493 13.5469
45
03BC: [email protected] = create_sphere_at 1695.4817 -2107.7493 13.5469 radius 2.0
46
0AD0: show_formatted_text_lowpriority "Drive to point!" time 4000
47
48
:MISSION_AA_LOOP
49
wait 0
50
if OR
51
car.Wrecked([email protected])
52
02BF: car [email protected] sunk
53
then
54
jump @MISSION_29_144_END_CAR
55
end
56
if
57
actor.Dead([email protected])
58
then
59
jump @MISSION_29_144_END_ACT
60
end
61
if OR
62
not actor.InCar($PLAYER_ACTOR, [email protected])
64
then
65
jump @MISSION_BB
66
end
67
if AND
68
actor.InCar($PLAYER_ACTOR, [email protected])
70
00EC: actor $PLAYER_ACTOR sphere 0 near_point 1695.4817 -2107.7493 radius 2.0 2.0
71
then
72
jump @MISSION_CC
73
end
74
75
if
77
then
78
jump @MISSION_AA_LOOP
79
end
80
if AND
83
then
84
0AD0: show_formatted_text_lowpriority "CJ: I drive car in point!" time 5000
87
end
88
if AND
91
then
92
0AD0: show_formatted_text_lowpriority "Friend: Ok. I sead down in this car!" time 5000
95
end
96
if AND
99
then
100
0AD0: show_formatted_text_lowpriority "CJ: This point in location Observatory!" time 5000
103
end
104
if AND
107
then
108
0AD0: show_formatted_text_lowpriority "Friend: I known. Is this car heavy?" time 5000
111
end
112
if AND
115
then
116
0AD0: show_formatted_text_lowpriority "CJ: No. Light." time 3000
119
end
120
if AND
123
then
124
0AD0: show_formatted_text_lowpriority "Friend: You drive very good!" time 5000
127
end
128
if AND
131
then
132
0AD0: show_formatted_text_lowpriority "CJd: Thank you! I drive vehicles very time" time 5000
135
end
137
jump @MISSION_AA_LOOP
138
139
:MISSION_BB
140
wait 0
141
marker.Disable([email protected])
142
03BD: destroy_sphere [email protected]
143
00BE: text_clear_all
144
[email protected] = marker.CreateAboveActor([email protected])
145
07E0: set_marker [email protected] type_to 1
146
[email protected] = marker.CreateAboveCar([email protected])
147
07E0: set_marker [email protected] type_to 1
148
0AD0: show_formatted_text_lowpriority "Hey, run in car!" time 4000
149
150
:MISSION_BB_LOOP
151
wait 0
152
if OR
153
car.Wrecked([email protected])
154
02BF: car [email protected] sunk
155
then
156
jump @MISSION_29_144_END_CAR
157
end
158
if
159
actor.Dead([email protected])
160
then
161
jump @MISSION_29_144_END_ACT
162
end
163
if AND
164
actor.InCar($PLAYER_ACTOR, [email protected])
166
then
167
jump @MISSION_AA
168
end
169
jump @MISSION_BB_LOOP
170
171
:MISSION_CC
172
marker.Disable([email protected])
173
03BD: destroy_sphere [email protected]
174
00BE: text_clear_all
175
player.CanMove(0, 0)
176
actor.SetImmunities($PLAYER_ACTOR, 1, 1, 1, 1, 1)
177
fade 0 1000
178
wait 1000
179
0633: AS_actor $PLAYER_ACTOR exit_car
180
181
while actor.InCar($PLAYER_ACTOR, [email protected])
182
wait 0
183
end
184
185
gosub @MISSION_END
186
actor.PutAt($PLAYER_ACTOR, 1698.6144, -2096.208, 12.5469)
187
actor.Angle($PLAYER_ACTOR) = 181.9148
188
camera.Restore_WithJumpCut
189
Camera.SetBehindPlayer
190
wait 500
191
fade 1 1000
192
wait 1000
193
player.CanMove(0, 1)
194
actor.SetImmunities($PLAYER_ACTOR, 0, 0, 0, 0, 0)
195
0394: play_music 1
196
00BA: show_text_styled GXT 'M_PASSR' time 5000 style 1 // MISSION PASSED
197
return
198
199
:MISSION_29_144
200
wait 0
201
gosub @MISSION_END
202
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
203
return
204
205
:MISSION_29_144_END_CAR
206
wait 0
207
gosub @MISSION_END
208
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
209
0AD0: show_formatted_text_lowpriority "You car wrecked!" time 4000
210
return
211
212
:MISSION_29_144_END_ACT
213
wait 0
214
gosub @MISSION_END
215
00BA: show_text_styled GXT 'M_FAIL' time 5000 style 1 // MISSION FAILED
216
0AD0: show_formatted_text_lowpriority "You Friend dai!" time 4000
217
return
218
219
:MISSION_END
220
wait 0
221
if
222
056D: actor [email protected] defined
223
then
224
actor.RemoveReferences([email protected])
225
actor.DestroyInstantly([email protected])
226
end
227
if
228
056E: car [email protected] defined
229
then
230
car.RemoveReferences([email protected])
231
if
232
not actor.InCar($PLAYER_ACTOR, [email protected])
233
then
234
car.Destroy([email protected])
235
end
236
end
237
marker.Disable([email protected])
238
marker.Disable([email protected])
239
03BD: destroy_sphere [email protected]
240
return
Copied!
Что же, это один из способов вывода текста последовательно, имитируя диалог между персонажами. Надеюсь, он поможет Вам у проектах ;)|1550|1|0||delaem_dialogi_v_missijakh|1504590898
Copy link
Edit on GitHub