XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Барахолка
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
prog

offline
Опыт: 32,865
Активность:
fly-script интерпретатор
Данные немного устарели, актуальная информация будет выложена в ближайшее время
((кат старое описание

немного рекламы

Хотите добавить в свою карту нестандартные заклинания, но приходите в ужас от слов jass, функции, переменные, дамми-каст и прочей невразумительной терминологии, а стащить у кого-то готовые не позволяет совесть или уровень знаний? Тогда ваше время пришло - знания одной-двух базовых команд fly-script достаточно чтобы создавать достаточно сложные способности, выходящие далеко за рамки стандартных, пользуясь при этом исключительно редактором объектов!
Являетесь достаточно опытным разработчиком готовитесь к старту нового проекта и с ужасом предвкушаете разработку очередной сотни героев с "уникальными" способностями? В состав fly-script входит набор команд, позволяющих использовать несколько распространенных механик работы способностей, которые можно комбинировать самым невероятным образом!
Вынашиваете планы грандиозной РПГ, дающей игроку возможность взаимодействия практически с любым элементом окружения, но не знаете как подступиться к решению этой задачи? Достаточно определиться со способом хранения fly-скриптов и условиями их передачи интерпретатору, после чего сразу можно приступать к заполнению вашего мира множеством интерактивных объектов!
Ваши идеи уникальны и базовых возможностей не хватает для их реализации? Архитектура fly-script позволяет легко и просто добавить собственную команду или изменить поведение любой стандартной!

общие сведения

язык реализации: cJass
целевая аудитория: как начинающие, так и опытные картостроители
работает в сетевой игре: да
версия warcraft: не ниже 1.24
Данная наработка представляет собой написанный на jass командный интерпретатор, выполняющий переданный ему текстовый скрипт. Текст скрипта разбивается на блоки, а блоки на команды с параметрами. Каждая команда обрабатывается соответствующей функцией, обычно расположенной в отдельном файле, а на основе результата ее выполнения принимается решение о переходе к следующей команде, завершении выполнения скрипта/блока, или даже пропуске нескольких последующих команд/блоков.
Для того чтобы пользоваться преимуществами fly-script не обязательно в совершенстве знать jass - после минимальной установки можно продолжать работу, пользуясь только редактором объектов и любым текстовым редактором поддерживающим кодировку UTF-8 для удобства хранения и редактирования скриптов. В базовой комплектации интерпретатор распознает использование способностей, содержащих fly-script и автоматически приступает к его исполнению.
В тоже время знание jass значительно расширяет горизонты применения fly-script, не ограничиваясь выполнением скрипта при использовании способности, не говоря уже о возможности добавления собственных команд.
Внимание, для тех кто в танке: Это не очередной преобразователь jass вроде сJass и vJass! Предполагается что текст скрипта будет храниться, например, в редакторе объектов или формироваться динамически.

текущее состояние

На данный момент система находится в активной разработке, но даже в текущем состоянии активно используется в двух проектах.
Установочный архив с черновой версией выложен, но без мануалов и даже без руководства по импорту. Использовать наработку до приведения ее к нормальному виду не рекомендуется
((кат краткий список команд доступных в базовой комплектации
cast дамми-каст стандартной способности по id и коду приказа, включает возможность выборки нескольких целей и различных правил расположения дамми
itm создание предмета или нескольких предметов по id
ifi проверка на наличие предмета в инвентаре, может быть указан произвольный код завершения
rem удаление предмета из инвентаря по id, номеру слота или номеру успешно выполненной команды ifi
irl переводит команды ifi и rem в продвинутый режим работы
abil добавление юниту способности по id, планируется включить также удаление и изменение уровня способности
sap изменяет значение указанного строкового регистра
msg выводит на экран текстовое сообщение, в качестве параметра может быть указан номер строкового регистра
ifs проверка состояния строкового регистра, может быть указан произвольный код завершения
to начать пропускать все последующие команды в блоке
do прекратить пропускать команды
bom перевод интерпретатора в режим работы, при котором неудачное выполнение любой команды проверки приводит к прерыванию выполнения текущего блока (если не указан фиксированный код завершения)
nom возврат к нормальному режиму работы, при котором неудачное выполнение команды проверки не приводит к прерыванию выполнения текущего блока
ret возврат указанного кода завершения
))
недостатки
  • из-за отсутствия в jass вменяемых команд работы со строками противопоказано использовать выполнение больших fly-скриптов по таймеру с малым периодом
  • на данный момент не распознаются равкоды стандартных способностей, исследований и предметов
  • код в некоторых местах требует рефакторинга и оптимизации
  • низкая документированность кода

требования и зависимости

минимальные
  1. JNGP с включенным cJass и vJass
  2. руки, мозг, умение читать и писать
  3. скачанный в этой теме установочный архив со всем содержимым
  4. умение работать в редакторе триггеров и редакторе обьектов
  5. версия warcraft: не ниже 1.24

импорт и настройка fly-script интерпретатора

минимальный вариант
  1. скопировать папку include туда где находится карта в которую импортируем
  2. скопировать триггеры системы в свою карту
  3. можно идти в РО и пытаться писать скрипты
  4. читать мануал по скриптам т.к. без мануала в них черт ногу сломит.
продвинутый вариант
  1. скопировать папку include туда где находится карта в которую импортируем
  2. скопировать триггеры системы в свою карту
  • открыть файл custom_registers.j и переопределить функции доступа к данным
  • в триггере Core в функции Init изменить список обрабатываемых команд
  • в триггере Actions убрать includ-ы ненужных команд
  1. можно идти в РО и пытаться писать скрипты
  2. читать мануал по скриптам т.к. без мануала в них черт ногу сломит.

планы на будущее

реальные
  • оптимизация и рефакторинг кода
  • расширение функциональности готовых команд
  • разработка новых команд
  • написание документации и мануалов
нереальные
  • разработка набора утилит и шаблонов для удобной генерации скриптов
  • объединение утилит и шаблонов под единой оболочкой
  • внедрение в WE
  • парсер и транслятор, позволяющие писать fly-скрипты прямо в jass коде с последующей трансляцией в обычный jass.

новости

Добавлена карта с системой кеширования скрипта. Поскольку до интерпретатора руки у меня еще не дошли - в карте просто кешируется любой введенный текст, а затем извлекается обратно.
Целочисленные и действительные параметры команд хранятся в виде целых и действительных чисел, соответственно, а команды - временно в виде хеш-кода строки команды, позже будет использоваться номер ячейки в массиве команд.
Кроме того система устойчива к неправильному использованию разделителей команд и параметров (а вот в коде относящемуся к разделителям блоков я что-то напутал и конструкции вида ## приводят к неправильной обработке скрипта)
Ну и еще одна новая возможность: можно указать собственные разделители для каждого скрипта - для этого достаточно начать скрипт с текущего разделителя блоков (по умолчанию #) и следующие три символа будут использованы в процессе обработки этого скрипта как разделитель блоков, разделитель команд и разделитель параметров, соответственно.
Теперь о главном, а именно когда же наконец демонстрационная карта с древней версией интерпретатора будет заменена новой со всеми этими свистелками-перделками и мануалом? Ответ до банального прост - вскоре после завершения сессии.
((кат текущее состояние обновления:

задачи

задача описание
переход на использование Library готово
регистры основных типов для хранения контекста скрипта готово
стек для передачи и временного хранения данных готово
кеширование на уровне скриптов готово
кеширование на уровне команд готово
кеширование на уровне параметров готово
задание нестандартных разделителей в скрипте готово
вызов команд кешированного скрипта готово
линейное выполнение кешированного скрипта готово
управление выполнением кешированного скрипта готово
немедленный переход к следующему блоку команд в разработке
механизм передачи контекста скрипта готово
распараллеливание кешированного скрипта в разработке
приостановка выполнения кешированного скрипта готово
кеширование на уровне списков параметров планируется

синтаксис

# разделитель блоков команд
! разделитель команд
пробел разделитель параметров
разделитель блоков в самом начале скрипта указывает парсеру что следующие три символа необходимо использовать при обработке как разделители блоков, команд и параметров, соответственно
строковые параметры необходимо заключать в двойные кавычки

планируемый список команд в минимальной конфигурации

внутренние команды:
команда описание состояние
nop Ничего не делает реализована
skip Интерпретатор начинает пропускать команды вплоть до конца блока или команды do реализована
do Восстанавливает нормальный режим работы после применения команды skip реализована
bom Переводит интерпретатор в режим, в котором выполнение команды с кодом завершения "проверяемое условие ложно" приводит к переходу к следующем блоку команд планируется
normal Возвращает интерпретатор в нормальный режим работы планируется
внешние команды:
команда параметры раздел описание состояние
ret Один параметр, строка или целое число Управление выполнением скрипта Возвращает указанный код завершения команды, основное предназначение - маппинг внутренних кодов завершения текстовыми константами реализована
wait Один действительный параметр Управление выполнением скрипта Перед выполением следующего блока команд будет сделана пауза на указанный промежуток времени реализована
loop Один целочисленный параметр Управление выполнением скрипта Следующий блок команд будет повторен указанное число раз реализована
msg Один строковый параметр Механизмы отладки Выводит сообщение красному игроку реализована
msg Один целочисленный и один строковый параметр Игровой процесс Выводит сообщение игроку с указанным номером реализована
group Номер группового регистра, режим работы, зависящие от режима работы действительные параметры, флаги Работа с данными Пикает группу юнитов по одному из алгоритмов (радиус, сектор, прямоугольник, прямоугольник с углом поворота) фильтрует в соответствии с флагами "свой/чужой" и помещает в указанный групповой регистр. Использует значения из некоторых регистров для сокращения списка параметров в разработке
group_ex Аналогично group Работа с данными Отличается от group дополнительным набором флагов, определяющих фильтрацию юнитов (живой, мертвый, здание, герой и т.д.) а также поведение в случае если групповой регистр уже содержит группу (добавить, перезаписать, выбрать совпадающих, выбрать различия) в разработке
cast Два номера unit-регистров, ID способности, ID приказа, флаги или режим работы Игровой процесс Дамми-каст указанной способности с использованием указанного приказа, флаги или режим работы определяют положение дамми, проверку "свой/чужой", наследование уровня способности. Первые два параметра могут быть опущены, тогда используются unit-регистры 0 и 1 в разработке
cast_group Номер unit-регистра, номер группового регистра, ID способности, ID приказа или строка приказа, флаги Игровой процесс дамми-каст указанной способности используя указанный приказ применительно к каждому юниту содержащемуся в указанном групповом регистре. Флаги определяют положение кастера, фильтрацию "свой/чужой", наследование уровня способности. Первый параметр может быть опущен, тогда используется unit-регистр 0. в разработке
cast_group_ex Аналогично cast_group Игровой процесс Отличается от group дополнительным набором флагов, определяющих фильтрацию юнитов (живой, мертвый, здание, герой и т.д.) в разработке
))
проекты, в которых используется fly-script 1.0
==============================
Племена
Warcraft Ant Wars
))
Прикрепленные файлы
Тип файла: zip fly-script.zip (37.1 Кбайт, 120 просмотров )
Тип файла: w3m script_caching.w3m (21.5 Кбайт, 95 просмотров )

Отредактировано prog, 21.02.2012 в 01:15.
Старый 08.05.2011, 02:31
SRes
1110101000
offline
Опыт: 9,997
Активность:
Цитата:
написанный на jass командный интерпретатор

nuff said. Писать на интерпретируемом скрипте интерпретируемый скрипт - это гарантированное убийство производительности.
Единственный вариант: написать свой транслятор из скрипта в JASS. Остальные идеи обречены на провал, ибо работают крайне медленно.
Цитата:
парсер и транслятор, позволяющие писать fly-скрипты прямо в jass коде с последующей трансляцией в обычный jass.

Без этого проект не имеет смысла. Да и с этим смысл невелик, разве-что для персонального использования.
Старый 08.05.2011, 03:26
prog

offline
Опыт: 32,865
Активность:
SRes, вынужден не согласиться. Да, действительно, производительность падает по сравнению с реализацией сразу на jass, но единственно из-за медленной работы со строками - после того как парсер выделил команду и ее параметры дальше выполняется уже чистый jass код, практически не отличающийся от того как бы он выглядел в реализации того-же самого функционала без всяких скриптов. Все остальные затраты процессорного времени возникающие в процессе работы интерпретатора не сравнимы с обработкой строк. Ах да, совсем забыл, сопоставление команды и функции которая ее обрабатывает реализовано через хештаблицу и TriggerEvaluate - на мой взгляд это быстрее чем последовательно сравнивать выполняемую команду с всеми возможными и вызывать соответствующую функцию при совпадении.
На самом деле правильнее было бы назвать это, например, макросами - такое название более точно описывает принципы работы получившегося чудища, но звучит не в пример хуже.
Старый 08.05.2011, 12:40
Elf_Stratigo

offline
Опыт: 4,699
Активность:
строки и хештаблицы - одни из самых медленных инструментов
сопоставление команды и функции которая ее обрабатывает реализовано через хештаблицу
в нормальном варианте это можно сделать через один массив
» ну а строки, типо
cls $0.ifi !<I000I002.sad $0 [ветка или трава] #
nop.ifi !<I002I00I.sad $0 [ветка или толстая ветка] #
nop.ifi !I001.sad $0 [камень] #
nop.ifs $0.sad $1 |c00ff0000Не хватает: .sad $1 $0.msg $1#
ifi <I000I002.ifi <I002I00I.ifi I001.rem all.itm I004#
читабельностью уж совсем не пахнут
имхо, совсем грустная вещь
Старый 08.05.2011, 13:39
Doc

offline
Опыт: 63,163
Активность:
омг, я пишу такую-же штуку, только круче и запутанней, с возможностью изменения синтаксиса на себя. И да, обработка строк не будет тормозить, имхо. У меня, например, она будет происходить только при переходе из одного блока заклинания к другому.
Старый 08.05.2011, 14:57
prog

offline
Опыт: 32,865
Активность:
Elf_Stratigo, будь добр объяснить как с помощью массива сопоставить практически произвольную строку длиной от 1 до 5 символов триггеру или функции без последовательного перебора всего массива... Одна операция чтения из хештаблицы однозначно быстрее чем, например, 20 операций чтения из массива.
((кат тот скрипт сейчас выглядит так:
@irl.ifi !<I000I002 >1.sap $1 [ветка или трава] #
@ifi !<I002I00I >1.sap $1 [ветка или толстая ветка] #
@ifi !I001 >1.sap $1 [камень] #
@ifs !$1 >3.rem.itm I004.to.msg $1000 $1#
))
В редакторе объектов, где этот скрипт и используется, оно вообще в одну строку пишется. Насчет плохой читаемости полностью согласен.
((кат вот так было-бы немного лучше:
@irl.ifi -$720 1.sap $1 $721#
@ifi -$430 1.sap $1 $431#
@ifi -$324 1.sap $1 $325#
@ifs -$1 3.rem.itm $330.to.msg $1000 $1#
))
Но что изменилось то? всего-навсего вынесены текстовые константы из скрипта, заменен символ отрицания и убран символ > перед кодом возврата в условиях. Изменить функции-обработчики команд таким образом чтобы они понимали сколь-угодно читаемый код может даже криворукий школьник, благо все обработчики команд вынесены в отдельные файлы и не надо судорожно искать их в коде карты.
((кат ах да, совсем забыл, можно же сделать что-то типа такого
1|0 -720 1|2 1 721#
0 -430 1|2 1 431#
0 -324 1|2 1 325#
0 -1 3|3|4 330|5|6 1000 1#
))
Тогда действительно можно обойтись без всякой хештаблицы - ведь команды заданы числами и да здравствует прирост производительности на 20%! за счет отказа от одного обращения к хештаблице на команду и сокращения длины строк из которых убраны избыточные символы.
А если кто-то подскажет мне способ как в редакторе объектов хранить byte-массивы то можно будет вообще уйти от строк и написать свой ассемблер.

Ну и для расширения кругозора:
((кат пример скрипта массового полиморфа из карты включенной в установочный архив
cast A001:polymorph 600 t#
))
имхо, достаточно читаемо и не создает чрезмерной нагрузки ни на мозг разработчика ни на движок вара.
prog добавил:
Doc, а можно подробнее или это секретная информация?
Старый 08.05.2011, 15:14
Doc

offline
Опыт: 63,163
Активность:
лечит всех союзов в области в области 500 на 50 хп, применяя на них эффект с названием "1", наносит 200 урона цели, применяя эффекты "1" и "2".
Старый 08.05.2011, 15:21
Elf_Stratigo

offline
Опыт: 4,699
Активность:
» используя тотже TriggerEvaluate и массив триггеров
#define MY_SUPER_ABILITIES = 'AT00'
trigger array mySuperTriggers

...

//trigger abilities dispatcher
void OnAbilityCasted(){
	int abilid = GetSpellAbilityId()
	
	if(abilid>=MY_SUPER_ABILITIES){
        TriggerEvaluate(mySuperTriggers[abilid-MY_SUPER_ABILITIES])
    }
}
считаем, что все абилки, требующие триггерного описания находятся с MY_SUPER_ABILITIES, благо ngen позволяет задавать свои равы
обычно задаю с верхнюю границу, но это сейчас не важно
пока ни один интерпретатор не выложен, неизвестно, что за магия у вас там
но если нету никакого кеширования действий, то при многократном частом использовании думаю будет очевидным появление лагов
впрочем, как заметил SRes, интерпретатор на интерпретаторе - это...
скорее это подходит для каких-нибудь рантайм "конструкторов заклинаний", когда поведение той или иной абилки зависит от самого игрока, а не значений РО

Отредактировано Elf_Stratigo, 08.05.2011 в 15:29.
Старый 08.05.2011, 15:21
Doc

offline
Опыт: 63,163
Активность:
там будет много модификаторов с разными параметрами итп.
Старый 08.05.2011, 15:22
prog

offline
Опыт: 32,865
Активность:
Elf_Stratigo, смотри первый пост - там уже появился архив
А твой метод не годится по одной простой причине - сопоставление идет вовсе не способности с триггером, а команды, например "cast" или "ifi" с соответствующей функцией обработки.
Ведь не только способностям можно назначать скрипты, если что - речь идет вовсе не о создании триггерных заклинаний как таковых - они используются только в качестве примера самого очевидного применения системы.
Doc, как я понял твоя система это по сути конструктор абилок и абилообразных действий? тогда у нас все-же немного разные системы - такое как у тебя я делал раньше, но до ума не довел - надоело модификаторы придумывать. Да и реализовано было намного примитивнее.
Например выложенный парой постов выше мой пример скрипта при выполнении от имени юнита проверяет наличие у того в инвентаре определенного набора предметов, выводит на экран хозяину юнита список всех недостающих ингредиентов, а если есть все необходимые - заменяет их на готовый предмет и молчит в тряпочку.
Старый 08.05.2011, 15:54
Elf_Stratigo

offline
Опыт: 4,699
Активность:
Хотите добавить в свою карту нестандартные заклинания
В базовой комплектации интерпретатор распознает использование способностей, содержащих fly-script и автоматически приступает к его исполнению.
выполнением скрипта при использовании способности
уж как объяснили
Старый 08.05.2011, 16:12
prog

offline
Опыт: 32,865
Активность:
Так это ж часть адресованная тем кто ни бум-бум в jass и не способен прикрутить интерпретатор куда ему надо.
Старый 08.05.2011, 16:16
Doc

offline
Опыт: 63,163
Активность:
намекает.
ну да, в целом у тебя более широконаправленная штука.

Отредактировано Doc, 08.05.2011 в 16:44.
Старый 08.05.2011, 16:32
prog

offline
Опыт: 32,865
Активность:
Doc, но при этом я немного теряю в производительности, в том числе, например, и за счет того что проверяется результат выполнения каждой команды, да и скрипт у меня получается далеко не такой компактный.
Кстати, если будешь выкладывать в открытый доступ - подумаю над тем чтобы научить свою систему пользоваться твоей, если ты не против, конечно. Естественно в виде изначально отключенной команды-обертки - твою систему обязательно надо будет ставить и настраивать отдельно.
Старый 08.05.2011, 17:22
Doc

offline
Опыт: 63,163
Активность:
prog, ок, поговорим как закончу.
наработку бегло посмотрел. круто, конечно. но я так и не понял, как ты вытаскиваешь данные из ро?
Старый 08.05.2011, 18:04
DotaMaster666
Silenced by GadenbIsh
offline
Опыт: 1,259
Активность:
У меня от кода глаза не на лоб, они куда дальше лезут.
» Шок контент
loop++.j
define <loop++>(i,x) = {loop ; exitwhen i> x}
define <loop+=>(i,x) = {loop ; exitwhen i>=x}
define <loop*++>(i,x) = {i = 0; loop ; exitwhen i> x}
define <loop*+=>(i,x) = {i = 0; loop ; exitwhen i>=x}
define <loop*++>(i,c,x) = {i = c; loop ; exitwhen i> x}
define <loop*+=>(i,c,x) = {i = c; loop ; exitwhen i>=x}

define <loop&++>(i,x) =   {integer i ; i = 0; loop ; exitwhen i > x}
define <loop&+=>(i,x) =   {integer i ; i = 0; loop ; exitwhen i >=x}
define <loop&++>(i,c,x) = {integer i ; i = c; loop ; exitwhen i > x}
define <loop&+=>(i,c,x) = {integer i ; i = c; loop ; exitwhen i >=x}

define <loop-->(i,x) = {loop ; exitwhen i< x}
define <loop-=>(i,x) = {loop ; exitwhen i<=x}
define <loop*-->(i,x) = {i = 0; loop ; exitwhen i< x}
define <loop*-=>(i,x) = {i = 0; loop ; exitwhen i<=x}
define <loop*-->(i,c,x) = {i = c; loop ; exitwhen i< x}
define <loop*-=>(i,c,x) = {i = c; loop ; exitwhen i<=x}

define <loop&-->(i,x) =   {integer i ; i = 0; loop ; exitwhen i< x}
define <loop&-=>(i,x) =   {integer i ; i = 0; loop ; exitwhen i<=x}
define <loop&-->(i,c,x) = {integer i ; i = c; loop ; exitwhen i< x}
define <loop&-=>(i,c,x) = {integer i ; i = c; loop ; exitwhen i<=x}

define <endloop++>(i)  = {i ++  ; endloop}
define <endloop++>(i,c) = {i +=c ; endloop}
define <endloop-->(i)  = {i --  ; endloop}
define <endloop-->(i,c) = {i -=c ; endloop}

...

loop&++(save_i,0,i)
   SET_REG_I(save_i,0)
   SET_REG_R(save_i,0.0)
   SET_REG_S(save_i,"")
   SET_REG_U(save_i,null)
   SET_REG_E(save_i,null)
   SET_REG_B(save_i,false)
endloop++(save_i)
Старый 08.05.2011, 18:18
prog

offline
Опыт: 32,865
Активность:
Doc, да здесь-же где-то, кажется, и вычитал про функции
GetAbilityEffectById
GetAbilitySoundById
первая работает и для юнитов, но немного коряво
для деструктаблов и предметов - можно попробовать в невидимом цветовом теге перед именем (хранить там, например, id способности, а уже в ней всю нужную информацию)
достаточно медленно, конечно, как мне кажется, поэтому есть смысл считывать эту информацию при загрузке карты и хранить в массивах или хотябы в хештаблицах (сам так пока не делаю, но чувствую что скоро придется)
DotaMaster666, к чему именно претензии? к моему cjass, или к не самому оптимальному способу сохранения/загрузки текущего состояния регистров интерпретатора, который, кстати, давно пора переделать в стек на основе глобального массива?

Отредактировано prog, 08.05.2011 в 18:45.
Старый 08.05.2011, 18:37
DotaMaster666
Silenced by GadenbIsh
offline
Опыт: 1,259
Активность:
Именно к cJass коду.
define ARR(t,name) = { t array ARRAY_##name }
define ARR(name)   = ARRAY_##name
ARRAY_ - тоже макрос?
Старый 08.05.2011, 18:46
prog

offline
Опыт: 32,865
Активность:
нет, это просто префикс чтобы снизить вероятность конфликта имен
посмотри там рядом есть еще макрос для имитации двухмерного массива на одномерном
Старый 08.05.2011, 18:56
DotaMaster666
Silenced by GadenbIsh
offline
Опыт: 1,259
Активность:
нет, это просто префикс чтобы снизить вероятность конфликта имен
Есть же vJass (они вместе с ц дополняют друг друга), там есть и много мерные массивы, и библиотеки с приватными именами. Я уже молу про использование в одной функции if () { и if () then...
А так это убивает всю читаемость на корню.
Старый 08.05.2011, 19:06
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 16:26.