Решил дать название движку - "Stacked Cubes" (это потому что тут кубики стоят столбиками друг на друге), а в связи с графическими экспериментами в PIC32 подумалось, что можно создать "Micro Edition" движка (на фиксированной точке и с меньшим разрешением текстур и малым количеством цветов) для заталкивания его в PIC32. Например - резмер текстуры, наклеиваемой на кубик, можно ограничить размером 8x8 пикселов, где каждый пиксел может быть раскрашен в один из 16 цветов (среди которых есть цвет прозрачности), т.е. имея 4 бита на точку, мы получаем 8*8/2=32 байта на текстуру (восемь 32-битных слов). Далее всё также будет 2 текстуры для пола и потолка в случае пустой клетки карты и 4 текстуры для боковых сторон кубика в случае заполненной - скажем мы всё также будем использовать 16-битный идентификатор текстуры, который будет использован как смещение внутри массива текстур - в результате имеем 4*2=8 байт для представления текстур клетки и нам надо ещё иметь информацию о количестве кубиков в столбике: cell[0]=количество стоящих друг над другом кубиков (младший байт) и тип клетки (старший байт); cell[1]=id1 - идентификатор текстуры первой стороны кубика либо пола если клетка пустая; cell[2]=id2 - идентификатор текстуры второй стороны кубика либо потолка если клетка пустая и у уровня есть потолок; cell[3]=id3 - идентификатор текстуры третьей стороны кубика либо возможная вторая текстура пола для анимации; cell[4]=id4 - идентификатор текстуры четвёртой стороны кубика либо дополнительная информация если клетка пустая. В старший байт нулевого параметра можно заложить тип клетки (болото, вода, лава, телепортер в пределах уровня, выход из уровня и т.д.), а опциональная дополнительная информация будет обозначать куда телепортируемся либо глубину воды и т.д.
P.S. Анимация путём переключения текстур наверное должна быть не только для пола, но и для потолка и не только из 2 текстур, но и из 3 (место есть). Надо помнить, что анимация невозможна (ну разве что только путём программной подмены текстур) для клеток, где стоят столбики кубиков - т.е. место отведённое под тип анимации можно перезадействовать подо что-то другое (например вариант выхода из уровня обозначать):
Code:
bit 15 - ceiling animation or E3 (N>0) bit 14 - floor animation or E2 (N>0) bit 13 - slow or fast animation or E1 bit 12 - 2 or 3 textures or E0 bit 11 -\ bit 10 --\ type of cell if empty (see below) or bit 9 --/ trigger identifier if occupied (trigger 0 means exit) bit 8 -/ bit 0...7 - N of stacked cubes (0 for empty cell)
Types of cell if empty: 0 - walkable 1 - exit (with code E0,E1 for empty cell without animation) 2 - teleporter (id3 is location) 3 - mover (id3 is direction and speed?) 4 - water (id3 is depth) 5 - swamp (id3 is speed) 6 - lava (id3 is temperature?) 7 - acid (id3 is acidness?) 8 - obstacle (id3 is object id?) 9...14 - other types 15 - trigger (id3 is identifier)
В начале июня 2009 решил было отпустить домен virtburg com и сконцентрироваться на оставшемся vburg.com, а щас вот думаю может продлить таки virtburg com и возможно даже прикупить обратно virtburg net?...
Прикупил обратно virtburg.net т.к. он до сих пор был свободен (правда пока не до конца понимаю для чего), а вот vburg.com (c 2012) и virtburg.com (с 2014) принадлежат каким-то жуликам-перепродавцам...
virtburg.com освободился и мне прислали какие-то левые ребята письмо:
Quote:
We are happy to inform you that virtburg.com is now available for purchase.
It is currently available at the affordable price of only 39.90.
We encourage you to secure it before it's taken by clicking here.
To no longer receive future emails from us, please click here.
"There is not much less vexation in the government of a private family than in the managing of an entire state." -Michel de Montaigne
Я просто пошёл и купил этот домен напрямую (через gandi.net) за $14.50 и послал ребятам благодарственное письмо за наводку Не понимаю честно на что они рассчитывают когда такие письма посылают ДО того как они собственно перехватили домен? Я уже второй раз таких "дельцов" обвожу вокруг пальца...
Ночью добавил управление от мыши - движения мыши переводятся в движения головы (влево-вправо-вверх-вниз), левая кнопка будет выстрел, колёсико - движение вперёд-назад, средняя и правая кнопка - пока не решил (возможно правая будет открывать двери и нажимать на кнопки, а среднюю можно попробовать задействовать для движения в сторону).
Вот видео (записанное кстати самой программой в виде отдельных кадров - 30 кадров в секунду - и затем собранных конвертером в avi) мышиного управления:
P.S. Для записи видео я ходил и бегал в реальном времени (см. на счётчик миллисекунд вверху) по трём секторам бывшего Виртбурга...
Смотрю насколько популярен Minecraft у моих дочек и жалею, что забросил свой 3D-движок в 2011...
Попробовал собрать исходники своего 3DM-движка (последний раз троганные в 2011 году) в современном C++ на Debian-линухе и обломался - слишком много ошибок (типа пренебрежение const и т.д.) и несовместимостей с последними стандартами
Надо чтоли сесть как-нибудь причесать этот код да уже и выложить в свободный доступ под названием Virtburg...
Попробовал собрать исходники своего 3DM-движка (последний раз троганные в 2011 году) в современном C++ на Debian-линухе и обломался - слишком много ошибок (типа пренебрежение const и т.д.) и несовместимостей с последними стандартами
Вот такой он "переносимый и кроссплатформенный" этот C++... С компилятора на другой компилятор пересядешь на одной платформе и уже куча ошибок. Хотя бы по-минимуму обратную совместимость поддерживали...
_________________ iLavr
25 Aug 2020 01:34
Shaos
Admin
Joined: 08 Jan 2003 23:22 Posts: 22588 Location: Silicon Valley
Попробовал собрать исходники своего 3DM-движка (последний раз троганные в 2011 году) в современном C++ на Debian-линухе и обломался - слишком много ошибок (типа пренебрежение const и т.д.) и несовместимостей с последними стандартами
Вот такой он "переносимый и кроссплатформенный" этот C++... С компилятора на другой компилятор пересядешь на одной платформе и уже куча ошибок. Хотя бы по-минимуму обратную совместимость поддерживали...
Ну там скорее стиль виноват в котором я кодил в конце 90х начале 00x - очень небезопасный стиль и современные компиляторы видят каждый потенциальный косяк
Причёсывание займёт какое-то время т.к. там больше 11 тысяч строк исходников - можно заодно на голый си перевести и слепить всё в один исходный файл
P.S. Выкладывать буду сюда: https://gitlab.com/shaos/virtburg (под MIT лицензией, чтобы код можно было включать в коммерческие проекты)
Теперь об оригинальном формате 3DMap (описатель комнат или секторов города) в том виде, как я его описывал более 18 лет назад:
Code:
############################################# # START.3DM - ФОРМАТ ФАЙЛА 3DM # # 17.09.2000 - 06.02.2002 # # Alexander Shabarshin (shaos@mail.ru) # ############################################# # 3DM (3D MAP) файл является текстовым ASCII # файлом, т.е. его можно редактировать в любом # простом текстовом редакторе (не Word!!!), # например в редакторе FARа или DOS-Naviagatora, # ну на худой конец в Нортоне или виндовом # Нотепаде (блокноте). В качестве просмотрщика # такого файла можно использовать программу # 3DM_VIEW.EXE которая работает под ДОСом и # принимает имя файла как аргумент. Управление в # программе почти такое же как в DOOM. Кроме того # PgUp и PgDn позволяют поднимать и опускать голову, # + и - на основной клавиатуре увеличивают и # уменьшают окно обзора, Q - включает/выключает # рисование текстур на полу, а S - включает/выключает # подпрыгивание в процессе ходьбы. Для работы # программы требуется файл TXRBASE.VDS, если вы # используете стандартный набор текстур из Виртбурга. # Можно также воспользоваться моей новой программой # 3DMap Wanderer (http://vburg.narod.ru, http://shaos.boom.ru) # которая работает в среде Windows-95 и позволяет # просматривать 3DM-миры как с вашего диска, так и # И З И Н Т Е Р Н Е Т А ! ! ! # Имя файла (или адрес в интернете) может задавться # как аргумент в командной строке. # Разберем небольшой примерчик START.3DM # (в-принципе весь этот текст есть 3DM файл :) # ------------------------------------------------
#3DMAP V1.2
# START 3D-MAP with 2D OBJECTS # Shaos (shaos@mail.ru)
# с символа # начинается строка комментария
map 11:13 # ключевым словом map задаем размер карты # в данном случае 11 клеток на 13 клеток
textures 16 # задаем максимальное количество текстур # причем описано их может быть меньше, чем указано # (для Виртбурга см."рекомендации")
t0000 gray01 # так мы описываем текстуры по порядку # нумерация начинается с 0000, числа шестнадцатиричные # далее в строке идет либо имя стандартной текстуры # из файла TXRBASE.VDS (см. список стандартных текстур), # либо имя файла текстуры из этого же подкаталога # (к имени добавляется расширение *.TXR), t0001 mypic.gif # можно подгрузить и свою текстуру, сохраненную в # формате GIF (можно использовать и GIF87, и GIF89, # причем последний допускает использовать прозрачность) t0002 w000 t0003 w000 +2 # тут мы сделали текстурку w000 чуть светлее t0004 gray02 *A0 # при желании можно трансформировать цвета текстуры # в любой цветовой диапазон палитры GAME.PAL # (в данном случае серая текстура трансформируется # в диапазон цветов 0xA0-0xAF) t0005 gray01 rama01 # таким способом мы можем наклеить текстуры друг на друга # (благо некотороые из них имеют "дырки", сквозь которые # могут просвечивать нижние слои) t0006 w000 +2 door01 t0007 mypic.gif "VIRTBURG" # а так можно писать на стенах :) t0008 @48 # так мы можем просто закрасить текстуру каким-либо цветом t0009 @48,3 # а так мы можем еще и добавить шум t000A rama01
back baseback.gif # без фона не обойтись - это файл BASEBACK.GIF 256-цветная # картинка в палитре GAME (для Фотошопа нужен файл # палитры GAME.ACT, или можно о палитрах и не думать, # но тогда программа сама подберет наиболее близкие # цвета из палитры GAME, что может выглядеть не совсем # эстетично ... ). Размер фона 1440 на 100 точек - # полная панорама в 360 градусов, причем начинается # панорама на севере (угол 90 градусов от оси Х)
start 5 1 90 # ставим игрока в точку (5,1) и направляем его взгляд # под углом 90 градусов от оси Х против часовой стрелки
default hh=0 t1=0 t0=a # за ключевым словом default следует описание # куба для всех клеток поля, hh=0 означает нулевую # высоту, а t1=0 означает, что на пол мы наклеиваем # текстуру t0000 # кроме того можно указать t0, что будет # означать текстуру на потолке (в случае hall)
border ex=10 hh=1 t1=2 t2=3 t3=2 t4=3 t0=a # за ключевым словом border мы описываем кубики, # которыми огораживается поле по периметру # ex=10 означает, что в клетке стоит столбик из кубиков # hh=1 означает высоту в один кубик (один этаж) # t1,t2,t3 и t4 задают номера текстур, котрые # следует наклеить на восточную, севрную, западную и южную # стороны кубика соответственно (в будущем # dd=цвет будет задавать цвет для верхушки столбика, # t0=номер будет задавать текстуру для верхушки, # hs=число будет задавать сколько текстур можно наклеить # на одну сторону - по порядку из списка снизу-вверх)
hall 2 # командой hall мы можем сообщить программе, что # хотим построить внутренность здания, причем # высота потолка будет равна 2 (если просто hall, то 1) # корректно поддерживается с версии 1.5
# fast # команда fast запрещает наклейку текстур на пол и потолок # (для медленных компьютеров)
^5,6 http://shaos.ru/vburg/50_51/main.3dm # а тут мы указали ссылку - в эту дверь можно "выйти" # и попасть в трехмерный мир в интернете # (напоминаю, что для того, чтобы ходить # в интернет нужна программа 3DMap Wanderer). # Ссылка на карте привязывается # к координатам - в данном случае (5,6)
^5,12 start.3dm 5 1 90 # кроме того можно в мире, на который ссылаемся, # поставить игрока в произвольные координаты (здесь - 5,1) # и направить его под любым углом (здесь 90 градусов)
5,12 ex=10 hh=1 t1=6 t2=6 t3=6 t4=6 # таким вот образом мы описываем все остальные # кубики в конкретных координатах
4-6,6-8 ex=10 hh=1 t1=5 t2=5 t3=5 t4=5 t0=a # таким образом задаются ряды из кубиков # очень удобно для описания зданий с длинными стенами
5,6 ex=10 hh=1 t1=7 t2=7 t3=7 t4=7 t0=a 5,7 ex=10 hh=10 t1=4 t2=4 t3=4 t4=4 # следует отметить, что hh=10 нужно читать как # шестнадцатиричное число, т.е. это значит 16 этажей
objects 2 # новинка версии 1.2 - возможность ставить объекты # указываем количество вводимых объектов, а затем # перечисляем их, начиная от 0 o0000 4.8 5.7 0 1.3 swin2.gif o0001 6.2 5.7 0 1.3 swin1.gif # за буковй o и шестнадцатиричным номером объекта # идут его координаты в карте (могут быть нецелыми), # высота размещения, видимый размер объекта в # единицах мира (напомним 1 единица - один этаж) # и имя файла картинки (GIF или TXR)
# scripts 2 # ну а об этом говорить пока рано ;)
end # команда, заканчивающая 3DM файл
В опенсорцной версии я планирую убрать GIF (т.к. там декодер с чужим копирайтом) и оставить только формат текстур TXR "изобретённый" мною в 1997 году: - первый байт задаёт размер по горизонтали в пикселах (максимальная ширина задаётся как 0=256) - второй байт задаёт размер по вертикали в пикселах (максимальная высота задаётся как 0=256) - далее идут пикселы слева-направо-сверху-вниз по одному байту на пиксел где байты задают такие цвета:
Attachment:
game_pal_big.gif [ 64.8 KiB | Viewed 9919 times ]
Последние четыре цвета скушались при конверсии в GIF, но на самом деле цвета от 0xc0 до 0xff задают 64 градации серого от чёрного до белого, а вот нулевой цвет означает прозрачность (если всё-таки в текстуре нужен чистый чёрный цвет, то надо использовать 0xc0 вместо 0x00)
P.S. В 2011 году я планировал убрать 3DMap формат совсем и заменить каждый сектор роботом, который будет его описывать программно на языке Robby:
Shaos wrote:
Подумалось, что если байткод может модифицировать уровень, то байткод может и генерировать уровень - т.е. язык описания уровней не нужен (во всяком случае пока) - просто всё пишем на языке RW1
P.P.S. А ещё в 2000 году я планировал сделать программу под винды, которая бы позволила строить сектора Виртбурга мышкой:
Quote:
VIRTBUILDER - программа, работающая под управлением ОС Microsoft Windows, которая поможет тебе создать свой собственный сектор для Виртбурга. Программа поддерживает 3 типа проектов:
.vbs (VirtBurg Sector) - проект стандартного сектора 64x64;
.vbb (VirtBurg Building) - проект здания, которое может быть вставлено в сектор;
.vbr (VirtBurg Room) - проект комнаты для здания, которую можно связать со зданием.
Эти проекты ты можешь создать через [File/New], загузить через [File/Open], или сохранить через [File/Save] или [File/Save as], а вот сектор в виде .3dm файла ты сможешь лишь экспортировать, а загружать не сможешь. Я запретил возможность открытия проекта на базе .3dm файла, чтобы у тебя не было соблазна стартовать свой проект с чужих разработок
Прототип выглядел вот так:
Attachment:
vbuilder.png [ 39.64 KiB | Viewed 9912 times ]
Сейчас вот думаю, что надо подобный редактор в онлайне делать...
P.S. В 2011 году я планировал убрать 3DMap формат совсем и заменить каждый сектор роботом, который будет его описывать программно на языке Robby
в Robby (RW1) применительно для Виртбурга (platform 3) предполагалось переиспользовать команды select и set - select x y выбирала бы клетку сектора для работы, а set задавала бы номер текстуры - причём у set изначально был скрытый второй параметр (по умолчанию 0), который может указывать сторону столбика в клетке, куда мы наклеиваем текстуру (по умолчанию получается что она наклеивалась бы на потолок), а вот объявление текстур в Robby изначально не предполагалось - тут придётся изгаляться, например через команду SAY говорить команды объявления текстур при старте робота типа:
Code:
SAY "\! t0004 gray02 *A0" SAY "\! t0005 gray01 rama01"
префикс \! будет говорить интерпретатору байткода, что это системные команды, которые идут мимо лога и не выводятся на консоль - вобщем как-то так...
P.S. Я смотрю прямая работа с текстурами всё таки предполагалась - через команды PLANE, COLOR, PIXEL, FILL и TEXT (и наверное CLEAR который в RW1P2 для ZX означал PIXEL цветом фона, а сейчас наверное можно прозрачным цветом номер 0) - другой вопрос, что скажем поточечное зашумление текстуры программно из байткода виртуальной машины будет медленным - так что наверное надо оба варианта доступа к текстурам иметь...
В оригинальном Виртбурге одномоментно рендерился только один сектор города - все здания остальных секторов были видны как плоские картинки в предварительно сгенерённой панораме (у других секторов свои другие панорамы т.к. набор окружающих зданий другой). Сейчас думаю наверное имело бы смысл рендерить 3x3 (9 секторов), причём игрок может ходить только в центральном секторе и за забором будут видны срендеренные здания соседних секторов, а всё что дальше будет в плоской панораме - так более качественный эффект присутствия будет. И при переходе на "киберпанк" дальние здания все будут в сером тумане со всякими световыми эффектами типа подсветки неба и т.д.
P.S. С другой стороны, если учесть вот такую статистику:
Shaos wrote:
Померял с секундомером скорости - если принять, что высота (и ширина) одного куба (один этаж) составляет около 2 метров, то игрок ходит со скоростью 17 км/ч, а бегает - со скоростью 50 км/ч (стометровку с такой скоростью можно пробежать за 7.2 секунды)
то пробегание от одного края сектора до другого займёт чуть больше 9 секунд - соответственно если клиент успеет за эти 9 секунд подгрузить и подготовить соседние сектора, в сторону которых двигается игрок, то стены между секторами можно вообще убрать...
Попробовал собрать исходники своего 3DM-движка (последний раз троганные в 2011 году) в современном C++ на Debian-линухе и обломался - слишком много ошибок (типа пренебрежение const и т.д.) и несовместимостей с последними стандартами
Вот такой он "переносимый и кроссплатформенный" этот C++... С компилятора на другой компилятор пересядешь на одной платформе и уже куча ошибок. Хотя бы по-минимуму обратную совместимость поддерживали...
Ну там скорее стиль виноват в котором я кодил в конце 90х начале 00x - очень небезопасный стиль и современные компиляторы видят каждый потенциальный косяк
Ворнинги ещё остались, а вот ошибки вычистил все - там только 2 типа ошибок было: 1) использование ключевого слова auto, которое в современных C++ компиляторах означает совсем другое (выводимый на этапе компиляции тип данных) - соответственно заменил все на register; 2) потребовалось заменить все long на int т.к. в 64-битных компиляторах под Intel тип long стал 64-битным, а int остался 32-битным.
P.S. В 2011 году я планировал убрать 3DMap формат совсем и заменить каждый сектор роботом, который будет его описывать программно на языке Robby
в Robby (RW1) применительно для Виртбурга (platform 3) предполагалось переиспользовать команды select и set - select x y выбирала бы клетку сектора для работы, а set задавала бы номер текстуры - причём у set изначально был скрытый второй параметр (по умолчанию 0), который может указывать сторону столбика в клетке, куда мы наклеиваем текстуру (по умолчанию получается что она наклеивалась бы на потолок), а вот объявление текстур в Robby изначально не предполагалось - тут придётся изгаляться, например через команду SAY говорить команды объявления текстур при старте робота типа:
Code:
SAY "\! t0004 gray02 *A0" SAY "\! t0005 gray01 rama01"
префикс \! будет говорить интерпретатору байткода, что это системные команды, которые идут мимо лога и не выводятся на консоль - вобщем как-то так...
P.S. Я смотрю прямая работа с текстурами всё таки предполагалась - через команды PLANE, COLOR, PIXEL, FILL и TEXT (и наверное CLEAR который в RW1P2 для ZX означал PIXEL цветом фона, а сейчас наверное можно прозрачным цветом номер 0) - другой вопрос, что скажем поточечное зашумление текстуры программно из байткода виртуальной машины будет медленным - так что наверное надо оба варианта доступа к текстурам иметь...
Ещё ведь нужно уметь не только текстуры для кубиков редактировать программно, но и спрайты (которые objects) - скажем обращаясь к ним через отрицательные номера в PLANE...
P.S. Хотя скорее их не редактировать надо, а перемещать в пространстве, а также прятать и снова показывать - cкажем через Robby команду COMMAND:
Code:
A=SpriteID B=New_x // x*64 (с точностью до пиксела) C=New_y // y*64 (с точностью до пиксела) COMMAND @SHOW_SPRITE // показать спрайт в указанных координатах
A=SpriteID B=New_elevation // z*64 (с точностью до пиксела) C=New_height // h*64 (видимая высота спрайта) COMMAND @JUMP_SPRITE // изменить высоту расположения спрайта, а также его видимый вертикальный размер
A=SpriteID B=Ptr_Text // указатель на память с текстом COMMAND @NAME_SPRITE // показать имя над спрайтом
Для начала опишу суть - город состоит из секторов 64х64 клетки, высота домов, в основном, до 16 этажей. Возможное количество секторов - 10000 штук (на июль 2001 их только 3).
Система координат:
Z ^ | /Y |/ +----> X
X и Y на плоскости, а ось Z направлена вверх (в первом 3dm-редакторе ось Y перевернута!).
На поле расположены кубики, на которых наклеены текстуры 64х64 пиксела в палитре game.pal.
Некоторые кубики пространства могут быть порталами - дверями в другие миры. Кроме кубиков на поле могут располагаться плоские объекты (как в DOOM). С помощью такого аппарата можно строить достаточно сложные миры, которые будут очень быстро выкачиваться из интернета.
Немного о внутреннем устройстве движка - карта (сектор) представляет из себя прямоугольное поле, составленное из столбиков (или "кубов" как я их называл т.к. всё начиналось с одноэтажных карт в 1997 году):
Code:
#pragma pack(1)
struct Cube { unsigned char ex; unsigned char hs; unsigned char dd; unsigned char hh; unsigned short id; unsigned short t0; unsigned short t1; unsigned short t2; unsigned short t3; unsigned short t4; };
#pragma pack()
И каждый из этих столбиков представлен 16 байтами (4 байта и 6 слов):
байт ex - тип куба пока может принимать только 2 значения: 0x00 - можно пройти и 0x10 - нельзя пройти (препятствие);
байт hs - сколько разных текстур можно наклеить на столбик (пока не поддержано);
байт dd - цвет для верхушки столбика (пока используется лишь при построении карты);
байт hh - высота столбика в кубиках (0 - пустая клетка, 1 - один этаж и т.д.);
слово id - идентификатор линка если есть (можно в будущем расширить вообще для абстрактных триггеров);
слово t0 - задаёт идентификатор текстуры для верхушки столбика (пока используется только для комнат как текстура на потолке);
слово t1 - идентификатор текстуры на восточной стороне столбика (если hh>=1) или текстуры на полу (если hh==0);
слово t2 - идентификатор текстуры на северной стороне столбика (невидно если hh==0);
слово t3 - идентификатор текстуры на западной стороне столбика (невидно если hh==0);
слово t4 - идентификатор текстуры на южной стороне столбика (невидно если hh==0).
По аналогии с описанной выше Micro Edition можно поддержать автоматическую анимацию для пола (для кубов без столбиков где hh=0) задействовав hs, которая предполагалась быть использованной только для столбиков высотой 2 и выше (чтобы разные текстуры клеить на одну сторону) - например старший нибл hs задавал бы частоту смены кадров в герцах, а младший нибл - сколько текстур ротейтится - 2, 3 или все 4 (задействовав полный набор t1,t2,t3,t4, причём t0 всё также останется на потолке)...
P.S. Вот нашёл в одной из старых тетрадок день, когда я впервые описал формат структуры Cube - 14 января 1998 года (правда dd и hs в то время предполагались использоваться для другого) и тогда же я пошёл вверх от одноэтажной реализации, по сути родив ранний прототип Виртбурга:
Attachment:
FirstCube.jpg [ 172.56 KiB | Viewed 9684 times ]
В то время я предполагал, что у меня кроме кубов ещё будут настоящие 3D объекты, т.к. эксперимент примерно в тоже время показал, что это вполне возможно, хоть и ресурсозатратно:
но я остановился на плоских спрайтах, которые добавил только летом 2001:
Users browsing this forum: No registered users and 84 guests
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum