> For the complete documentation index, see [llms.txt](https://lessons.sannybuilder.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lessons.sannybuilder.com/00100/00200/tekst/000158.-dinamicheskaya-gxt-tablica-ili-virtualnye-gxt-zapisi.md).

# 000158. Динамическая GXT-таблица или виртуальные GXT-записи

Динамическая GXT-таблица или виртуальные GXT-записи|Всем привет! С Вами wmysterio, и сегодня мы рассмотрим небольшую тему, связанную с игровыми текстами.|wmysterio|wmysterio||||В [этом](https://github.com/wmysterio/scm-scripting-lessons/blob/main/publ/uroki_skriptinga/gta_sa/rabota_s_tekstom/34-1-0-35/README.md) уроке мы рассматривали возможность создания текстовых таблиц ( GXT-таблицы ). Теперь у нас появилась возможность создавать такие таблицы динамически ( их называют ещё виртуальными ), прямо в скрипте. Таким образом мы изучим четвёртый способ использования текстовый тип данных. Напомню, что ранее мы было опубликовано такие темы как FXT-архивы, форматированный текст и GXT-таблицы.

Для добавления в динамичную таблицу текста в скрипте мы должны использовать следующий опкод:

```
0ADF: add_dynamic_GXT_entry "DYNTABL" text "My test string"
```

Здесь:\
"DYNTABL" - имя поля в нашей виртуальной таблице. Важно! Длина имени должна составлять не больше 7 символов, как и в обычной GXT- или FXT-записи. Кроме этого, они обязательно должны быть взяты именно в двойные кавычки.\
"My test string" - содержание поля

Для удаления нужно использовать:

```
0AE0: remove_dynamic_GXT_entry "DYNTABL"
```

Здесь:\
"DYNTABL" - имя поля в нашей виртуальной таблице.

Также нам доступны следующие опкоды, которые помогают избежать вылетов или неточностей:

```
0ADE: 0@ = text_by_GXT_entry 0@v
```

Получает позицию входа записи в виртуальной таблице, где:

Здесь:\
0@ - переменная, в которую будет записана позиция строки 0\@v в таблице

Также мы можем получать длину строки, что иногда полезно при рисовании на экране:

```
09FD: get_gxt_string 'XSELECT' width_to 0@
0A08: get_gxt_string_1number 'XSELECT' number 1@ width_to 0@
```

Здесь:\
'XSELECT' - имя записи\
1@ - значение, которое будет подставлено вместо \~1\~\
0@ - переменная, в которою запишется длина

Кроме этого, нам доступна важная проверка, которая проверяет на пустоту строки. Полезно, когда строка не загрузилась и нам не пришлось потом выводить деформированную запись:

```
0844: string s$GXT_NAME empty
```

Здесь:\
s$GXT\_NAME - имя записи

Давайте напишем скрипт, который будет последовательно выводить текст:

```
{$CLEO}
wait 2000
0ADF: add_dynamic_GXT_entry "DYNTABL" text "My test string ~1~"

for 0@ = 0 to 5
01E5: show_text_1number_highpriority GXT 'DYNTABL' number 0@ time 1000 flag 1
wait 1000
end

0AE0: remove_dynamic_GXT_entry "DYNTABL"
0A93: end_custom_thread
```

Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/77832249.png)\
\
× \*\*ВАЖНО:\*\* Кода мы заполняли виртуальную таблицу записями, мы использовали её как vСтрока, но обращаться к самой записи мы должны как sСтроке

Рассмотрим пример с массивами. Здесь дела интереснее. Я потратил целый день, чтобы составить адекватный алгоритм, который будет работоспособным для панели, которую я и предлагаю сделать сейчас.

Для начала нам необходимо объявить 2 массива, чтобы сократить код с помощью цикла:

```
var
$TAB_NAME: array 5 of string
$TAB_LIST: array 5 of longstring
end
```

$TAB\_NAME будет отвечать за имя виртуальной GXT-записи. Второй массив $TAB\_LIST будет отвечать за содержимое записи ( **vСтрока** ), поэтому тип указываем как **longstring**. Далее заполняем наш массив значениями и создаём виртуальную GXT-таблицу в цикле:

```
s$TAB_NAME[0] = 'DYNTAB0'
s$TAB_NAME[1] = 'DYNTAB1'
s$TAB_NAME[2] = 'DYNTAB2'
s$TAB_NAME[3] = 'DYNTAB3'
s$TAB_NAME[4] = 'DYNTAB4'
 
v$TAB_LIST[0] = "Black_Admiral" 
v$TAB_LIST[1] = "Sanchez_as_Bike" 
v$TAB_LIST[2] = "Remingtn"
v$TAB_LIST[3] = "Hotrina_Car" 
v$TAB_LIST[4] = "Monster"

for $INDEX = 0 to 4
0ADF: add_dynamic_GXT_entry $TAB_NAME[$INDEX] text $TAB_LIST[$INDEX] 
end
```

Здесь главное указывать значения для s$TAB\_NAME длиной не больше **7** символов. В противном случае таблица будет пустой. Значения для v$TAB\_LIST заполняем как обычно.

× \*\*ВАЖНО:\*\* Я заметил, что по-умолчанию игнорируются все пробелы при выводе текста. Чтобы игра адекватно отображала этот символ, его нужно подменить на символ '\*\*\_\*\*'. В таком формате символ пробела отображается как и ожидалось

Заполнение массива в цикле должно быть без приставок **v** или **s** возле переменных. После этого мы можем вывести панель ( таблицу ):

```
08D4: 1@ = create_panel_with_title 'DUMMY' position 29.0 170.0 width 200.0 columns 1 interactive 1 background 1 alignment 0
08DB: set_panel 1@ column 0 header 'DUMMY' data s$TAB_NAME[0] s$TAB_NAME[1] s$TAB_NAME[2] s$TAB_NAME[3] s$TAB_NAME[4] 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY'
```

Дальше нужно использовать короткие строки ( 8-ми байтные ), по-этому возле массива указываем s$TAB\_NAME а не v$TAB\_NAME. Когда панель нам больше не нужна, выгружаем виртуальную таблицу GXT-записей:

```
for $INDEX = 0 to 4
0AE0: remove_dynamic_GXT_entry $TAB_NAME[$INDEX]
end
```

Полный код скрипта будет следующим:

```
{$CLEO}
0000: NOP

var
$TAB_NAME: array 5 of string
$TAB_LIST: array 5 of longstring
end

s$TAB_NAME[0] = 'DYNTAB0'
s$TAB_NAME[1] = 'DYNTAB1'
s$TAB_NAME[2] = 'DYNTAB2'
s$TAB_NAME[3] = 'DYNTAB3'
s$TAB_NAME[4] = 'DYNTAB4'
 
v$TAB_LIST[0] = "Black_Admiral" 
v$TAB_LIST[1] = "Sanchez_as_Bike" 
v$TAB_LIST[2] = "Remingtn"
v$TAB_LIST[3] = "Hotrina_Car" 
v$TAB_LIST[4] = "Monster"

for $INDEX = 0 to 4
0ADF: add_dynamic_GXT_entry $TAB_NAME[$INDEX] text $TAB_LIST[$INDEX] 
end

08D4: 1@ = create_panel_with_title 'DUMMY' position 29.0 170.0 width 200.0 columns 1 interactive 1 background 1 alignment 0 // Imports
08DB: set_panel 1@ column 0 header 'DUMMY' data s$TAB_NAME[0] s$TAB_NAME[1] s$TAB_NAME[2] s$TAB_NAME[3] s$TAB_NAME[4] 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY' 'DUMMY'

while true
wait 0
 08D7: 0@ = panel 1@ active_row
 if
 0AB0: key_pressed 32 // SPACE
 then
 if
 0@ == 0
 then
 Player.Money($PLAYER_CHAR) += 1000
 break
 else
 break
 end
 end
end

08DA: remove_panel 1@

for $INDEX = 0 to 4
0AE0: remove_dynamic_GXT_entry $TAB_NAME[$INDEX]
end

0A93: end_custom_thread
```

Суть этого скрипта проста: нажимаем пробел - панель убирается. Если при этом выбрана первая строка, то даём в придачу ещё 1000 долларов. Результат:

![](https://github.com/wmysterio/scm-scripting-lessons/raw/resources/_pu/2/21104994.png)

Также я заметил, что важно ещё и то, что массивы вступают в силу только тогда, когда весь код скрипта не приводит к ошибке. Это очень плохо, потому, что нельзя узнать будет отображаться текст или нет. Возможно ( и я надеюсь ), что это только у меня так :)

На этом всё. С Вами был wmysterio, до встречи в новых уроках!|1636|1|0|21104994`png`1280`768`400`240``\|77832249`png`600`360`400`240\`\`||dinamicheskie\_tesktovye\_gxt\_tablicy|1504601423
