воскресенье, 28 февраля 2016 г.

"Случай в квадрате 36-80" или "Операция Святой Януарий".

Когда-то достаточно давно я видел оба фильма. И их названия очень даже соответствовали моим извращениям по поиску алгоритма генерации блоков ландшафта. Как я уже говорил ранее, совершенно необязательно грузить весь огромный террайн, если в игре ты видишь максимум десятую часть егог (в лучшем случае). Как я писал в предыдущем посте, террайн разбивается на множество квадратных блоков, из которых на активный слой грузятся те, которые в данный момент должны присутствовать под камерой. И вот тут началось самое интересное...
Для начала о "Случай в квадрате 36-80". Фильм был снят в начале 80-х, небезызвестным режиссером Михаилом Туманишвили, который также был автором фильмов  "В зоне особого внимания" и "Ответный ход". Также в свое время он "перековался" в соответствии с 2демократическими веяниями" и снял фильм "Сто дней до приказа". За что был нещадно бит в прессе и на ковре у тогда еще советского руководства Минкультуры. Затем он перековался еще раз и снял относительно недавно еще один патриотический боевик "Ноль седьмой меняет курс". Пересказывать содержание фильмов я не буду, тем более, что "Сто дней" не смотрел - если есть желание - сами найдете. Могу только сказать, что хотя все вышеперечисленные фильмы (за исключением "Ста дней" это агитка наоборот) являются агитками, как сейчас модно "заклеймит" все, не соответствующее либеральному взгляду (анекдот середины 90-х: "В России существуют два взгляда в экономике и политике - один - либеральный, второй - неправильный"), смотреть эти фильмы можно. Если выкинуть на время просмотра из головы некоторые детали. Например, что "новейшая система заправки крыло в крыло" к началу 80-х уже была признана устаревшей, или что для ремонта реактора совершенно необязательна кувалда (хотя кто его знает, может, даже сейчас у нас найдутся умельцы, способные починить Большой Адронный Коллайдер этим инструментом), а также то, что Ту-16, как и заправщик на его базе, с отключенными по причине израсходования топлива, планирует чуть лучше брошенного кирпича, ну и для запуска крылатых ракет с подводной лодки нужно проделать много нудных манипуляций, да и выдающиеся боевые и летные качества СВВП Як-38 вызывают сомнения... Но все же уровень "Случая в квадрате 36-80" будет повыше, чем у многих американских агиток (например лично видел в каком-то боевике эпизод с советским офицером-подводником, носящим почему-то фуражку явно не черного цвета, да еще и с красным околышем (!!!) или играющих в карты советских же подводников в фильме "К-19"). Впрочем, киноляпов можно вспомнить много, но в данный момент интересен мой BGE-ляп.
Итак, мне нужно было сделать запись в текстовый файл типа:

b|30|29|Terrain.2499|110000.0|90000.0|0.0|
b|45|29|Terrain.2498|410000.4375|90000.0|0.0|
b|46|29|Terrain.2497|430000.4375|90000.0|0.0|
b|45|13|Terrain.2496|410000.4375|-230000.515625|0.0|
b|46|13|Terrain.2495|430000.4375|-230000.515625|0.0|

Первые две цифры - индексы квадрата по Х и У. Индексы 0-0 соответствуют самому дальнему левому нижнему блоку ландшафта, а 49-49 - самому дальнему правому верхнему блоку ландшафта. Соответственно координаты по Х и у у этих блоков будут минимальными и максимальными. Далее я задумывал следующую операцию - уже во время игры следовало определение квадрата, в котором находится активная камера. определялся он по формуле:

quadroX = int((int(parentCam.worldPosition[0]/1000)+ 490)/20)
quadroY = int((int(parentCam.worldPosition[1]/1000)+ 490)/20)

В данном случае - 490 - поправка с учетом отрицательных координат части блоков (можно было бы и оставить минус перед блоками, но непривычно так именовать квадраты, да и сложилось как-то по ходу дела). Далее следует открытие списка и поиск в нем нужных индексов в диапазоне от минус до плюс (справ и слева, сверху и снизу от квадрата, над которым висит камера). и их генерация. в коде это выглядит так:

#Отыскиваем и открываем нужный нам текстовый файл с названиями, координатами и значениями квадратов для блоков ландшафта
    brikeLand = open(bge.logic.expandPath('//Terrain/Terrain_2_/BlockTerrain_2.txt'),'r')
   
    #Дальше по маркерам смотрим, что нам нужно
    for string in brikeLand:
        if string[0] == '#':
            continue
        elif string[0] == 'b':
            tempList = string.split('|')
            X = int(tempList[1])
            Y = int(tempList[2])
            #print(X, Y)
            #Вычисляем индексы квадратов, нужных для вызова
            #Если индексы квадрата по ХУ находятся внутри требуемого диапазона - добавляем название блока ландшафта в список
            #нужных для появления блоков
            if quadroY-2 < Y < quadroY+2 and quadroX-2 < X < quadroX+2:
                    listBlock.append(tempList[3])
                    blockLand = scene.addObject(tempList[3], own)
                    blockLand.worldPosition = [float(tempList[4]), float(tempList[5]), float(tempList[6])]
                   
                    
    brikeLand.close()

Как выяснилось позже, алгоритм был верен. НО! Когда я в файле с террайном создавал этот самый текстовый список с индексами, названиями и координатами, я тупо отсортировал все блоки террейна по возрастанию координат Х и у и записал индексы элементов этиъ списков в файл. ОШИБКА! Во-первых, имеются 50 блоков с одной и той же координатой, во-вторых,  индексы блоков должны быть в диапазоне от 0 до 49. у меня же максимальный индекс был 2499! И в соем террайне НИКАК не могло быть квадрата 36-80 (теперь, думаю понятен смысл первой части названия этого поста).

Потратив три дня на составление скриптов, разбивку ландшафта на блоки и попытку осознать, что я сделал не так, решение с индексами квадратов было найдено. На мой взгляд несколько коряво, но работающее. и, как ни странно, работающее довольно быстро. Если взглянуть на мой террайн, то координаты каждого его отдельного блока находятся в определнном диапазоне, начиная от -49000 до 49000. Как по Х, так и по У. Шаг составляет 20000. Поскольку в процессе присвоения новых центров нарезанным блокам были отклонения, типа, -37020. 08739, то пришлось опять немного изощриться...
 Я создал список такого вида [-49, -47, -45...45, 47, 49] Из 50 чисел от -49 до 49 , с шагом в 2. Это были примерные координаты центров блоков. И ввел для них поправки плюс-минус 1. Я специально опустил четыре нуля позади чисел в списке, чтобы выглядело попроше. Поправки с нулями были уже в коде:

for obj in scene.objects:
    if 'Terrain' in obj.name:
       
        X, Y, Z = obj.worldPosition
       
        try:
            for coordX in listCoord:
                if  (coordX-1)*10000 < X < (coordX+1)*10000:
                    blockX = listCoord.index(coordX)
               
            for coordY in listCoord:
                if  (coordY-1)*10000 < Y < (coordY+1)*10000:
                    blockY = listCoord.index(coordY) 
       
       
            coordText = open(bge.logic.expandPath('//BlockTerrain_2.txt'),'a')
            coordText.write('b|' + str(blockX) + '|' + str(blockY) + '|' + obj.name + '|'+ str(X)+'|'+str(Y) +'|'+ str(Z)+'|'+'\n')
            coordText.close()
        except:
            pass

Часть кода симпортом модулей и стандартных функций со списками я опустил - и так разберетесь. Поясню лишь, что, скажем нижний левый блок имеет координаты в пределах от -48000 до -50000 (то бишь -49-1 и -49+1, если отбросить нули. Точные его координаты и так прописаны в текстовом файле, нам же нужно знать, индексы блока для их записи в текстовый файл. Так вот у блока в нижнем левом углу обе кординаты соответствуют -49 и имеют нулевой индекс в списке [-49...49]. аналогично - для всех 2500 блоков. Отмечу, что скрипт, задействованный в файле террайна в самой игре не используется, мне он был нужен лишь для составления текстового файла, который-то как раз и используется в самой игре. Скрипт получился очень простым и довольно быстрым, даже жаль, что в игре он не нужен. А перед этим была перепробована уйма способов, и все они были отброшены. по сложности и скорости исполнения они, мягко говоря, были попросту не нужны.
Это называется - "ломиться в открытую дверь". И заодно напомнило мне эпизод из итальянской комедии "Операция Святой Януарий". Когда банда американских гангстеров вместе с их итальянскими коллегами пыталась вскрыть витрину с драгоценностями в соборе. Применялось все - хитроумные отмычки, сверхпрочные сверла, зубила. Закончилось все тем, что главный герой фильма с досады швырнул зажигалку в бронестекло... и оно рассыпалось. Теперь ясно и со второй частью названия этого поста.
А теперь немного полюбуемся на результаты. Первый скрин - сгенеренные 9 блоков ландшафта. Камера висит на приличной высоте, и видно, что сгенерились именно те 9 блоков, которые были нужны. Если бы камера находилась на высоте хотя бы 20 км, блоки заняли бы все поле зрения, даже с некоторым запасом. Кстати, как потом до меня дошло, в процессе опробования скрипта с неверными индексами списка, генерились бы блоки по левым и нижнему краю, наподобие буквы L. Очень смешно...

Второй и третий скрины - это небольшой оффтоп - очень давно я скачал свободно распространяемые модели с cайта http://www.sharecg.com/  и посмотрел, как они выглядят в Блендере. вряд ли они будут задействованы в самой игре, по крайней мере в том виде, в котором они есть сейчас, но мысль, что неплохо бы ввести старые машины, полагающиеся не на умные ракеты, а на старые добрые пушки и пулеметы, у меня мелькала не раз.


воскресенье, 21 февраля 2016 г.

Ландшафт, интуиция в нодах...

Как-то повторяю я дао denis8424... Вот, значит, подошел вплотную к созданию рабочего ландшафта. Первого, поскольку рассчитываю, минимум на два. Для начала. И для начала же - это будут абстрактные ландшафты, не имеющего ничего общего с реальной географией планеты Земля. Надеюсь, временно. Подсказанные denis8424 нодовые материалы мне столь полюбились, что я их и сюда запихнул. Правда, с учетом прежних ошибок - выкрутил блеск на матералах земли почти до нуля.
Безусловно, самые острые ощущения доставили нарезка пЭйзажа на блоки и регулировка текстур и их смешивание на нодовом материале. Самый же большой прикол заключается в том, что смешивание и разделение текстур по высоте я выставил "от балды". Поскольку до этого в ходе нескольких неудачных попыток  ничего особо тоолком не добился. Беда в том, что у меня нулеквой уровень - это нулевая координата Z. Если спустить ландшафт на минус 100-200 метров, то текстуры прекрасно смешивались, но стоило только выровнять "фундамент" с нулем - все сыпалось. К тому же не знал, как быстро и четко можно нарезать ландшафт на блоки. спасибо, коллегам с b3d, подсказал stark, потом Mihanik дополнил. Иначе неделю бы провозился. Ну да, герои не ищут легких путей - жмем В и выделяем область на ландшафте, отделяем, потом соседнюю, потом еще и еще. Потом еще дробим уже полученные области на части. В итоге с этим безобразием было покончено сегодня за полчаса, из которых 15 минут было потрачено на накладывание нодового материала. Видимо, Высокое Небо таки решило надоумить незадачливого игродела и при третьей попытке я, выкрутив значения в нодах Mapping наугад, переключился в просмотр и вытаращил глаза - это было то, что мне было нужно. А до этого, значит, недели не хватило.
Размеры ландшафта велики, чего уж там... Область 1200 на 1200 км. Максимальная высота - около 2 км. Много ровной поверхности, горы имеются. Террайн разрезан на 1024 блока, каждый блок имеет размер 37,5  км по границам. У меня в первой версии видимость камеры в небе достигала 40 км, вообще-то я рассчитываю сделать регулируемую видимость в этот раз и не злоупотреблять черным дымом от горящей техники. Пока, по моим расчетам, размеров блока хватит.
Псоле порезки ландшафта и интуитивного регулирования нодового материала пустил в ход скрипт переименования объектов и мешей - педантичность в данном случае никогда не лишняя. После перименования всех блоков в BigDesert.001 и так далее выяснилось, что один блок не имеет числовой приставки. Отыскав его, я мстительно залепил ему дополнение к имени .1024 ("Кто был ничем, тот станет всем" наоборот, да). Заодно протестировал ландшафт на способность удерживать на себе динамические объекты. И вот тут выяснилась любопытная вещь, собственно, я о ней знал и раньше, просто при первой встрече посчитал, что бесконесными переделками ландшафта что-то испортил (в первой версии). Оказалось - нет. Если в окне Physics для нодовых материалов поставить галочку, то ландшафт спокойно удерживает динамические объекты и не дает им проваливаться, но если эту галочку убрать, все - тушите свет - динамический куб медленно провалился сквозь землю.
Теперь необходимо писать скрипт генерации нужных блоков ландшафта. А сами блоки надо загонять в отдельные файлы. Как это сделать - пока не знаю (я имею в виду скриптом, вручную-то, разумеется ничего сложно - знай себе открывай исходный файл, оставляй один блок и сохраняй под нужным именем.и все ручками, ручками).
Что-то у меня картинки увеличиваться не хотят...
Сам ландшафт выглядит так(с высоты 900 км, спутник, прямо), с текстурой и без;






воскресенье, 7 февраля 2016 г.

Тяжелый рестарт и Fuck Windows!

Долгое время не писал на тему игростроения и своего проекта. Причина была довольно банальная - серия неудач и метания с поисками. Поскольку первая версия блендер-симулятора вполне доказала свою работоспособность, но в тоже время, в силу своих изначально заложенных особенностей, она оказалась достаточно закрытой структурой, тяжело поддающейся модернизации. Окончательно заставило меня заняться второй версией невозможность, скажем так, обеспечить онлайн-версию игры. Мои знакомые и друзья прямо говорят о необходимости этой "фичи". Раз надо, значит, придется делать. Хотя я не поклонник онлайн-игр, да и со своим модемом и "отличной" связью много не наиграю, да и как-то получилось в последнее время, что игры для меня стали своего рода "мониторным учебником" - любопытно взглянуть, как выглядит эффект взрыва, облака, посмотреть на террайн там... Зачастую вполне хватает роликов на ютубе.
Примерно дня четыре назад была найдена разгадка странного поведения replaceMesh в БГЕ. При замене мешей для МиГ-23/27 консоль начинала ругаться на некорректное поведение создаваемых мешей, причем часть мешей все равно менялась, а часть не появлялась (по крайней мере, так это выглядело на экране). Повидимому, при создании исходных мешей вкралась ошибка, которая потом размножилась с отделением в самостоятельные объекты частей юнитов. Ничего удивительного (теперь), поскольку самолеты создавались очень давно в еще версии 2.6, потом переделывались в других версиях... Лечение  этого безобразия было проведено с помощью экспорта моделей в obj и последующим импортом полученных объектов обратно. Разумеется, пришлось потом переименовывать, расставлять центры объектов заново и так далее, но работа того стоила - после создания экспериментального файла со скриптом замены мешей консоль молчала, а объекты исправно менялись. И тут возникла еще одна проблема. Самолеты, как правило, состоят из множества объектов (закрылки, предкрылки, стабилизаторы, рули, фонари кабины, про шасси вообще молчу). Особенностью моего кода является то, что он завязан на использование похожих имен. Причем для замены мешей КРАЙНЕ необходимо, чтобы имена объектов и мешей совпадали полностью или частично. А теперь картина маслом: сидит перед монитором человек и лихорадочно щелкает мышью то по имени объекта в N-панели, то по имени меша в боковой панели свойств. и объектов, гм, много... Представили, да? Эпичное зрелище. Особенно , если я не дожму и промажу по клавише, а потом, при подгрузке файла и запуске процесса замены мешей консоль выразится в том смысле, что такого меша в сцене нет.  Придется опять открывать файл и искать ошибку. И устранять. Ручками, ручками... Все это надоело и я задался вопросом, нельзя ли сей процесс автоматизировать. Ответ - в Блендере все можно, надо только знать, как. В итоге подошел к вопросу создания аддона массового приведения в соответствие имен объектов и мешей, но пока ограничился запуском RunScript вручную (раньше я не понимал, зачем нужна эта кнопка в текстовом редакторе Блендера, теперь дошло, радость-то какая, можно было бы и раньше поинтересоваться).
Сам код был составлен denis8424 в ответ на мои неуклюжие попытки чего-то изобразить самому.
import bpy

scene = bpy.context.scene

for ob in scene.objects:
    if ob.layers[scene.active_layer] == True and ob.name != 'Camera':
        newName = 'prefix' + ob.name.split('.')[0]
        ob.name = newName
        ob.data.name = ob.name

В данном мини-скрипте 'prefix' - это набираемая ручками приставка к имени объекта. Все же это гораздо удобнее, чем выделять объекты по одному и менять у них имена. префикс можно разместить перед или за именем объекта или сделать несколько приставок к именам. Для объектов второй версии игры выстраивается своя архитектура имен. приведу отрывок из пишущейся параллельно документации:  

 Все юниты состоят из нескольких объектов, меши которых в исходном состоянии малодетализированы.
Смена уровней детализации осуществляется путем замены исходных мешей на высокодетализированные.
В целях автоматизации процесса замены мешей и проигрывания анимации имена мешей и анимаций пол-
ностью или частично совпадают. Точнее, полностью совпадают имена исходных мешей и названия аним-
маций, которые должны эти самые меши исполнять. Сама замена мешей осуществляется по команде с объ-
екта родителя, который и отслеживает требуемый уровень детализации.

Структура имени исходного меша:
"сокращенное название семейства" + "сокращенное название детали"
Пример: FLM_FldL0_ - Fulcrum("FLM") + Fold("Fld") + Left("L") + 0
Означает МиГ-29, створка шасси, левая, номер ноль

Структура имени вызываемого на замену меша:
"сокращенное название семейства" + "сокращенное название детали" + "модификация юнита" + "национальность юнита"
Пример: FLM_FldL0_MiG-29A_IrAF_ - Fulcrum("FLM") + Fold("Fld") + Left("L") + 0 + MiG-29A("MiG-29A") + IrAF("IrAF")
Означает МиГ-29, створка шасси, левая, номер ноль, МиГ-29А, ВВС Ирака

В состав имени вводится разделитель "_" - для удобства

Название семейства задается заглавными латинскими буквами, и представляет собой сокращение от натовской кодировки
военной техники (примечание: для наземки можно и так - Т72, Т62, М1А и так далее).

Список сокращений

Семейства ЛА:
FSC - Fresco - МиГ-17
FAM - Farmer - МиГ-19
FLM - Fulcrum МиГ-29
FLG - Flogger МиГ-23/27
FXB - Foxbat МиГ-25
FLN - Flanker Су-27
FRF - Frogfoot - Су-25
FNR - Fencer - Су-24
FBD - Fishbed - МиГ-21
FRA - Fitter Су-7
FRB - Fitter Су-17/20/22
EGL - Eagle F-15
FFL - Fighting Falcon F-16
TMT - Tomcat F-14
TGR - Tiger F-5
PNT - Phantom F-4
VDO - Voodoo F-101
ARR - Aardwark F-111
SKW - Skyhowk A-4
SKR - Skyrider A-1
INR - Intruder A-6
TND - Thunderbolt A-10
TCF - Thunderchief F-105



Детали юнитов
Trr - Turret - башня, турель
Cnn - Canon - пушка, ствол, ПУ
Crp - Corpus - корпус
Cnp - Canopy - фонарь кабины
Arb - Airbrake - воздушный тормоз
Slt - Salaty - предкрылок
Flp - Flaps - закрылок
Fln - Flaperon - флаперон
Inp - Interceptor - интерцептор
Fus - Fuselage - фюзеляж
Wng - Wing - крыло
Cns - Consol - консоль крыла (поворотная)
Rdd - Rudder - руль направления
Fld - Fold - створка шасси
Aln - Ailieron - элерон
Elv - Elevator - руль высоты (стабилизатор)
Cck - Cockpit - кабина
Whl - Wheel - колесо

Собственно, принцип построения юнитов и их поведение в игре здесь и приведены. Добавлю только, что в связи с ненужностью в игре практически все время деталей шасси с их анимациями, они будут подгружаться лишь при выполнении взлета или ипосадка. Также для экономии ресурсов сама модель может быть анимированной детализированной (вблизи, когда можно разглядеть работу элеронов, рулей и прочей механики) и детализированной, неанимированной (по сути - один объект - вся механика объединена с фюзеляжем в один меш) - это для тех случаев, когда самолет можно рассмотреть довольно подробно, но работа его механизации практически незаметна. фактически создаются две системы детализации, третья - отдельная система - это детали шасси, она стоит особняком, когда используется - писал выше. И к этому стоит добавить "чистый" лоуполи LOD - очень грубо изготовленный меш, скорее напоминающий силуэт, который используется на больших дистанциях, где самолет выглядит либо точкой, либо черточкой или какой-то серо-черной тенью. Большаую часть времени в игре юнит проводит именно так. Или на совсем уж больших дистанциях, надобность даже в этом отпадает - хватит и треугольника.
Во второй версии создается с нуля сама архитектура игры. Она планируется более гибкой, с возможностью добавления дополнений и модов. К тому же, опять же с целью экономии ресурсов, планируется загрузка конкретных объектов, а не всего пакета вооружения, например. Зачем нужна масса ракет и бомб, если в данной миссии используется два-три типа из сотни?
Кстати, об оружии. созданный мною для первой версии пакет вооружения был проверен на замену мешей, ошибок выявлено не было, поэтому последовало его "дробление" на отдельные папки типа R-27R, R-13S, AGM-65E, AIM-120C-5  и так далее. Имя им легион - набор вооружения был резко расширен, особенно в части крылатых ракет, наших и иностранных.
Та же процедура планируется в отношении пилонов подвески вооружения для самолетов и вертолетов, контейнеров постановки помех и других "суб-объектов". Да, количество файлов возрастет весьма резко, но не составит труда легко добавить или заменить любую пеапку (если придерживаться некоторых правил, естественно, которые еще только создаются, кхе-кхе).
И вот тут началось самое интересное. Я обладаю несомненным талантом создавать проблемы на ровном месте, где их по определению, вроде не должно быть...
Для управления всей этой армадой файлов во второй версии крайне необходим алгоритм поиска файлов и путей к ним. Казалось бы, функция listdir  в модуле os - наше все. Увы... denis8424  в своем боле кратко выразился насчет "слэшей не этой системы в Винде". Я поражаюсь его терпению. Переписка была весьма оживленной. Сначала моя Винда тупо повторяла, что файлы не найдены. Разобрались - пути к файлам в Винде  с одной стороны и во всех прочих (!) с другой отличаются разными слешами - с наклоном влево (Винда, прямо левацкий уклон, троцкизм какой-то, 58-ая статья) и нормальным правым наклоном (нормальный рабочий почерк человека с наклоном вправо, встречаются, правда некоторые личности, у которых наклоны могут быть и вправо и влево - видел сам, но не будем о грустном). - это Линукс и прочие FreeBSD. После правки скрипта Винда узрела объекты для поиска и.. отказалась их идентифицировать! В ее интерепретации - это не файл, не папка и не ссылка. На вопрос, заданный мною в монитор: "А что это вообще такое?", ответа, понятное дело не последовало. неведома звершка, не иначе. Чебурашка. Fuck Windows! Проблему опять решил denis8424, з0а что я ему весьма благодарен. http://denis8424.blogspot.ru/
Фактически, на его скрипте и будет держаться вторая версия. На базе этого скрипта планирую создать инструменты обновления, меню, подгрузки объектов, защиту от ошибок... Не моделями и не графикой едиными жива игра. Хотя и они важны, не скрою.
Все это время с перерывами, пилю модели для второй версии. часть, конечно, будет взята из первой версии, но часть будет либо обновлена либо создана заново. Сегодня вот, взялся за Су-30МК. пока показывать особо нечего, там идет процесс ретопологии, сама модель не моя, пак с ними выложил человек в далеком 2003 году.  В паке, который я, по своей хомячиной природе, заначил еще пару лет назад, есть Су-27, Су-33, Су-27ИБ (ныне Су-34), расшивки на них нет, если рассматривать вблизи, то видна "покорябання2 сетка - неровная, явно со следами булевых вырезаний, полигонов гораздо больше, чем нужно, но это не брюзжание - это превосходная исодная модель для создания своих юнитов. к тому же, в отличие от того же МиГ-23, Су-17, МиГ-21 и еще многих машин, наших или иностранных, для новейших "Сушек" нет чертежей с поперечными сечениями. А без них строить модель сложнее на порядок. Но вообще, по замыслу, в игру можно будет вставить все что угодно, соблюдая простенькие правила. Так и до наземки можно добраться. или в космос слетать... Ладно, надеюсь, у читающих сей опус, хватило терпения дочитать его до конца, да и не стоит сильно предаваться мечтаниям, хотя мечтать вроде и не вредно... Да еще и прошлый пост по ирано-иракской надо доделывать - картинки искать и детали уточнять.