Вопрос по респаунам BirthPlace появился.
Есть набор эскадрилий, у каждой на вооружении стоят определенные самолеты. Задача - изменение плейнсета на аэродроме в зависимости от находящихся на нем эскадрилий.
При загрузке миссии читается файл сохранения, откуда берется список эскадрилий и аэродромы на которых они базируются, далее в цикле каждая авиачасть добавляется на свой аэродром. При этом удаляется старый респаун с таким же именем и создается новый. Но тут я не учел время на загрузку подмиссии с респауном(а он создается как подмиссия). Получается что удаления не происходит, т.к. респаун еще не был загружен. В результате загружаются все подмиссии с респаунами и для каждой эскадрилии создается свой отдельный с таким же именем(кол-во респаунов равно кол-во добавленных эскадрилий, т.к. неактуальные не удаляются). При получении массива выглядит это примерно так:
Создано два респауна Dieppe_Saint_Aubin с одинаковыми координатами, но активный тот, что создан первым(где доступны только спиты). Это не дает быстро менять доступные самолеты на аэродромах, нужно вводить какую-то задержку для загрузки подмиссии с респауном.Код:[22:23:16] Server to [podvoxx]: [TEST]: BirthPlace [Dieppe_Saint_Aubin] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.SpitfireMkIIa] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.SpitfireMkI] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.SpitfireMkIa] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.SpitfireMkIa_100oct] [22:23:16] Server to [podvoxx]: [TEST]: BirthPlace [Grandvilliers] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.HurricaneMkI_100oct] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.HurricaneMkI_dH5-20] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.HurricaneMkI] [22:23:16] Server to [podvoxx]: [TEST]: BirthPlace [Deauville_Saint_Gatien] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.HurricaneMkI_100oct] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.HurricaneMkI_dH5-20] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.HurricaneMkI] [22:23:16] Server to [podvoxx]: [TEST]: BirthPlace [Montdidier] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.BlenheimMkIV] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.DH82A] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.BR-20M] [22:23:16] Server to [podvoxx]: [TEST]: BirthPlace [Dieppe_Saint_Aubin] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.SpitfireMkIIa] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.SpitfireMkI] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.SpitfireMkIa] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.SpitfireMkIa_100oct] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.BlenheimMkIV] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.DH82A] [22:23:16] Server to [podvoxx]: [TEST]: at [Aircraft.BR-20M]
Вопрос такой. Возможно ли создание BirthPlace не используя подмиссию(чтобы сразу получить над ним контроль, не дожидаясь загрузки подмиссии)?
Возможно ли модифицировать уже созданный BirthPlace(поменять настройки, изменить список самолетов). Нашел пока только методы для чтения параметров BirthPlace.
Если нельзя ни первое ни второе хотелось бы, чтобы в будущем такая возможность была(подмиссии неудобны для динамичных респаунов). Также пригодилось бы событие на создание BirthPlace.
Ну и может какой-нибудь совет кто-то даст, как в таком случае решить проблему корректной замены респауна на новый с удалением старого(так как именно он выбирается при клике на карте).
Я пока придумал вариант с периодическим(например 5-10 сек) сканированием массива GamePlay.gpBirthPlaces() и при наличии в нем BirthPlace с одинаковыми именами удалять имеющие меньший индекс, но это будут постоянные проверки в OnTickGame()
Крайний раз редактировалось podvoxx; 04.12.2012 в 09:22.
я бы просто в миссию с BirthPlace-ом из списка все доступные самолёты добавлял и эту миссию грузил - получится на одном аэродроме - один спаун, с доступными самолётами, не надо никаких таймеров и т.п. что-то типа такого -а в Вашем варианте, более поздние не доступны скорее не потому-что удаляться не успевают, а стоят в одной точке и при клике на них берётся какой-то верхний из списка. Ну либо надо вокруг аэродрома их расставлять, чтобы не в одной точке были.Код:ISectionFile f = GamePlay.gpCreateSectionFile(); string sect; string key; string value; for (int i = 0; i < список аэродромов.length; i++) { sect = "BirthPlace"; key = список аэродромов[i].name; string Country = "."; if (army == 1) Country = "gb"; // страну выбираем if (army == 2) Country = "de"; value = " " + army.ToString() + " " + (список аэродромов[i].x).ToString() + " " + (список аэродромов[i].y).ToString() + " 0 " + BPMaxPlanesAllowed + " " + BPSpawnParked + " 0 " + Country + " . ."; f.add(sect, key, value); sect = "BirthPlace" + список аэродромов[i].name; string[] PlaneSet = список нужных самолётов; if (PlaneSet.Length > 0) for (int j = 0; j < PlaneSet.Length; j++) { key = PlaneSet[j]; value = ""; f.add(sect, key, value); } } GamePlay.gpPostMissionLoad(f);
нет, создать без миссии или модифицировать нельзя, только дестроить и читать св-ва.
ну вот как выше написал, например, по событию когда надо сменить спаун - удаляете старый и генерите миссию в которой в одном спауне все нужные самолёты прописаны(у меня правда для списка аэродромов написано но для одного то-же самое будет, без верхнего цикла), мне кажется это оптимальный вариант.
Don't happy, be worry
Я так и сделал, но так как респауны постоянно меняются, а время загрузки подмиссии выходит за пределы методов, то только что созданные респауны не обрабатываются(не загрузились). Еще попробую сделать что-то вроде очереди событий типа удалить/создать, которые будут добавляться в список и обрабатываться по таймеру последовательно и учитывать время на загрузку подмиссии. А лучше наверное в событии OnMissionLoaded поставить на проверку - если есть уже такой респаун просто заменять его
Да, при загрузке миссии эскадрилии добавляются на аэродром и "обновляют" респауны за очень маленький промежуток времени(по логу - в пределах одной секунды, в следующую секунду уже идет сообщение о загрузке подмиссий, но к этому времени все эскадрилии распределены). Такая же ситуация может случится при одновременном перебазировании
Don't happy, be worry
Они обновляются, только когда добавляются эскадрилии на аэродром, что-то вроде Airfield.Add(Sqadron Name). Добавление происходит при загрузке миссии, при отступлении с потерянной территории, при перебазировании. В методе Add происходит сначала удаление старого респауна с тем же именем(если он есть) и загрузка подмисии с новым(в котором изменяется только список доступных самолетов). Загрузка подмиссии происходит независимо от выполнения метода Add в том смысле, что добавлено уже несколько эскадрилий, а респаун еще не один не загрузился. Timeout я не могу в коде dll поставить, да и неправильно это будет так как неизвестно сколько миссия грузится. Т.е. проблема в том, что нет метода который бы создавал респаун и только после него код исполнялся дальше, сейчас одно с другим не связано. Было бы проще при возможности изменять список самолетов/вооружения уже созданных респаунов - тогда их можно было бы создать "пустыми" заранее и управлять уже только параметрами.
OnMissionLoaded позволит сделать "пошаговую" загрузку - даже если код по созданию респаунов уже выполнен здесь можно проверить результат и убрать ненужные респауны.
Ага, так вроде бы понятнее, Airfield.Add может приключаться в любой, заранее не известный момент времени и для каждого аэродрома их может быть любое количество, так? Если так и у аэродрома есть список эскадрилий на нём, я бы в конце метода Add вызвал бы функцию, которая удаляла бы спаун с именем аэродрома(если такой уже есть) и генерировала миссию со спауном в который записывались бы все доступные эскадрильи/самолёты и грузила бы её, тогда после крайнего Add-а для аэродрома всегда на нём будет актуальный спаун. Ну а если списка нет - тогда сделать его для аэродрома, и в Add добавлять сначала эскадрилью в этот список, а потом запускать рефреш спауна для этого аэродрома.
Don't happy, be worry
Примерно так я и сделал(или даже точно также, список и рефреш есть), но проблема появляется из-за отсутствия времени на загрузку подмиссии. Либо нужно метод Add делать индивидуальный для загрузки сохранения(чтобы сначала собирался список самолетов и потом только один раз создавался респаун). Такой же метод нужно использовать при отступлении на ближайшие аэродромы - если сейчас я последовательно перебрасываю методом Add более двух эскадрилий - подмиссия тоже не успеет загрузиться(нужно будет сначала сформировать общий список и только потом менять респаун).
Хотел сделать блокировку аэродромов по результату падения бомб на взлетку, однако нашел только такие типы поверхности:
Есть способ определить падение бомбы именно на ВПП?Код:LandTypes gpLandType(double x, double y); public enum LandTypes { NONE = 0, CITY = 16, ROAD = 32, RAIL = 64, HIGHWAY = 128, WATER = 28, OBJECTS_MASK = 3, ROAD_MASK = 224 }
И по приведенному выше хотелось бы уточнить как этим пользоваться. Номер означает цвет?
Непонятно значение NONE, OBJECTS_MASK и ROAD_MASK.
И что подразумевается под CITY? Это только города или деревни тоже? Если так можно определить падение бомбы на город, то отлично - можно расширить триггеры(сейчас я зону бомбежки по ним задаю) до максимального радиуса, а в зачет пойдут только бомбы упавшие и вызывающие CITY. Если это маска, то она есть в ресурсах игры?(возможность их посмотреть у меня есть)
ВПП - это ROAD в границах аэродрома.
номер - это значение элемента в перечислении, можно использовать как номер, так и текстовое значение.
ROAD_MASK - это одно из ROAD,RAIL,HIGHWAY можно с результатом с помощью "|","&" и т.д. сравнивать. А вот с CITY сейчас посмотрел - плохо, он не работает корректно, корректно работают дороги, вода. OBJECTS_MASK - это внутренний тип используеся в редакторе только.
Don't happy, be worry
Парни! Простите за нубский вопрос. AiAircraft и классы из part не позволяют определить какую систему измерения использует панель приборов данного крафта, не хотелось бы переопределять классы (память), по армии же будет не слишком универсально (что там серверострители удумают?), ни у кого идей нет на этот счет?
a` la guerre comme a` la guerre
profile: Core i5-3570K 3.4GHz, ASUS GTX660 2Gb GDDR5, ASUS GT520 Silent 1Gb, LCD 1600x1200x32 IPS, LCD 1600x1200x32 MVA, LCD 800х600 TFT,
RAM DDR3 32GB, OCZ Vertex 4 128 Gb, OCZ Vertex 450 128 Gb, 4xHDD WD 1 Tb FAEX, RAID10, WD 2 Tb FAEX, Win 7 x64, БП FSP 600Вт
lepage.sytes.net:21000
А не переопределяй классы. переопредели поведение.
Я не в курсе, как у тебя все устроено, но к примеру.
public double AircraftObserver.GetIAS(IMeasureConverter converter)
где AircraftObserver твой класс, который следит за самолетом.
GetIAS метод, возвращающий IAS
IMeasureConverter интерфейс, ответственный за перевод значений из одной системы в другую. Содержит набор методов для перевода м/с в что-то еще, метры в что-то еще и т.п. AircraftObserver получает сырые данные и переводит их в требуемый формат, используя класс с этим интерфейсом.
Можно класс этот к примеру вообще в конструкторе передавать.
Юзер к примеру может сам выбрать, в какой системе ему данные возвращать. Тогда скажем класс UserDefinitions будет в одном из свойств содержать конкретную, нужную именно этому юзеру реализацию IMeasureConverter. Оттуда ее берем и передаем в методе GetIAS и остальных.
Т.е. у тебя будет набор "переводчиков" IMeasureConverter на все случаи жизни, подставляй нужный.
Спасибо! Мда, так мыслить классами мне еще учиться и учиться. Правда, мне этот вариант не совсем подходит.
Задача - определить какие данные идут, преобразовать их не проблема (можно и на клиенте).
Так сказать для аутентичной внешней панели, чтоб она сама настраивалась : идут данные в футах (игрок выбрал английски самолет) - панель натягивает скин с приборами в британской системе, идут метры - скин с приборами в метрической системе. Как-то так.
Не найду свойство однозначно определяющее страну-производителя самолета
a` la guerre comme a` la guerre
profile: Core i5-3570K 3.4GHz, ASUS GTX660 2Gb GDDR5, ASUS GT520 Silent 1Gb, LCD 1600x1200x32 IPS, LCD 1600x1200x32 MVA, LCD 800х600 TFT,
RAM DDR3 32GB, OCZ Vertex 4 128 Gb, OCZ Vertex 450 128 Gb, 4xHDD WD 1 Tb FAEX, RAID10, WD 2 Tb FAEX, Win 7 x64, БП FSP 600Вт
lepage.sytes.net:21000
Страна-производитель, имхо, тебе мало поможет. Потому что у одной и той же страны та же скорость может измеряться и в милях и в узлах (поправьте, если не прав).
Я бы примерно вот так сделал, навскидку.
Класс AircraftObserver, уже упомянутый. В OnTickGame обновляет состояние; смотрит за GamePlay.gpPlayer().Place() - самолет/что угодно, где сидит игрок в сингл-плеере.
Он же, в зависимости от того, что в GamePlay.gpPlayer().Place() создает требуемый конкретный экземпляр IMeasureConverter (по стране, по типу самолета или предпочтениям юзера)
Структура, скажем AircraftParameters, содержащая снятые в текущей итерации данные по самолету и идентификатор скина, согласно текущему IMeasureConverter
В AircraftObserver публичный метод, возвращающий текущую AircraftParameters по запросу с клиента. Данные сериализуются и отправляется клиенту.
Клиент на основании полученных данных ставит нужный скин и нужные положения стрелочек/индикаторов. Все.
Можно вообще задачу перевода из одной системы в другую отдать клиенту, что бы сама миссия поменьше считала, отдавать сырые данные и идентификатор скина/"во что надо переводить".
Крайний раз редактировалось Small_Bee; 09.12.2012 в 21:19.
Вот и где их найти?
Так и хочу, но getParameter отдает данные в системе конкретных приборов кокпита, если пересел с мерса в спит данные тут-же идут уже в футах/милях. И вот ищу этот «идентификатор скина», сиречь идентификатор кокпита. Есть возможность читать абсолютные данные (Z_Orientation и т.д., они всегда в метрах) как сейчас сделал в версии Beta 2.3, но это немного читерно , в онлайн точно не стоит.Можно вообще задачу перевода из одной системы в другую отдать клиенту, что бы сама миссия поменьше считала, отдавать сырые данные и идентификатор скина/"во что надо переводить".
Крайний раз редактировалось LePage; 09.12.2012 в 22:18.
a` la guerre comme a` la guerre
profile: Core i5-3570K 3.4GHz, ASUS GTX660 2Gb GDDR5, ASUS GT520 Silent 1Gb, LCD 1600x1200x32 IPS, LCD 1600x1200x32 MVA, LCD 800х600 TFT,
RAM DDR3 32GB, OCZ Vertex 4 128 Gb, OCZ Vertex 450 128 Gb, 4xHDD WD 1 Tb FAEX, RAID10, WD 2 Tb FAEX, Win 7 x64, БП FSP 600Вт
lepage.sytes.net:21000
Брать самолет, смотреть какие у него там приборы и в чем передают, и делать конвертер персонально. По каждому летабу. После смотреть на AiAircraft.InternalTypeName() и подставлять соответствующий.
Например будет у тебя метод IMeasureConverter GetConverterForAircraft(string internalTypeName).
Отсюда (примерный код)
Код:AiAircraft airc = GamePlay.gpPlayer().Place() as AiAircraft; if (airc != null) { IMeasureConverter converter = GetConverterForAircraft(airc.InternalTypeName()); AircraftObserver observer = new AircraftObserver(airc, converter); // юзаем observer; }
--- Добавлено ---
Если сделаешь онлайн, а после объяснишь, как сделал, цены тебе не будет!
Спасибо за AiAircraft.InternalTypeName(). Имхо, проще его значение передать клиенту и там отпарсить на предмет модели крафта. И уже понятно в чем данные идут.
Эх, жаль нет подробного описания на манер этого http://www.sukhoi.ru/forum/attachmen...7&d=1311685400
Naryv, у Вас еще чего нибудь подобного не завалялось в закромах?
С онлайном, ИМХО, думаю так, как и сейчас поднимать HTTP-сервер в хост-миссии на дедикейтед-сервере, передавать ему хост-миссию, по IP идентифицировать игрока, и отсылать ему данные по его запросу + плюшки по управлению геймплеем. Оценочный траффик 100 кбит/с на игрока.
a` la guerre comme a` la guerre
profile: Core i5-3570K 3.4GHz, ASUS GTX660 2Gb GDDR5, ASUS GT520 Silent 1Gb, LCD 1600x1200x32 IPS, LCD 1600x1200x32 MVA, LCD 800х600 TFT,
RAM DDR3 32GB, OCZ Vertex 4 128 Gb, OCZ Vertex 450 128 Gb, 4xHDD WD 1 Tb FAEX, RAID10, WD 2 Tb FAEX, Win 7 x64, БП FSP 600Вт
lepage.sytes.net:21000
Нифига в студии неясно. maddox.game.world.AiAircraft.TypedName(), maddox.game.world.AiAircraft.Type(), maddox.game.world.AiActor.Name(), maddox.game.world.AiCart.InternalTypeName() : все что про них написано - тип и член . Найдите 10 отличий.
з/ы/ Разработчики вроде писали что просчет миссий вынесли в отдельный поток? Но и сам НТТР-сервер простой до безобразия.
a` la guerre comme a` la guerre
profile: Core i5-3570K 3.4GHz, ASUS GTX660 2Gb GDDR5, ASUS GT520 Silent 1Gb, LCD 1600x1200x32 IPS, LCD 1600x1200x32 MVA, LCD 800х600 TFT,
RAM DDR3 32GB, OCZ Vertex 4 128 Gb, OCZ Vertex 450 128 Gb, 4xHDD WD 1 Tb FAEX, RAID10, WD 2 Tb FAEX, Win 7 x64, БП FSP 600Вт
lepage.sytes.net:21000