-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
...тип получаем через InternalTypeName()
Ага. Спасибо! Реализовать это свойство удалось в такой части кода:
Код:
Zena = (actor as AiCart).InternalTypeName().ToString();
if (actor.Army() == 1 && Zena == "bob:Artillery.Krupp_L2H43_Protze_Flak38")
{
Red_Zenitka_Killed++;
Sss("Количество подбитых красных зениток стало равно: " + Red_Zenitka_Killed.ToString());
}
Странно только то, что условие правильно работает лишь тогда, когда я этот (actor as AiCart).InternalTypeName().ToString() предварительно загоняю в переменную Zena. Ну, да это ладно. Пашет и слава Богу!
Другой вопрос. Имеем такую миссию.
[Stationary]
Static81 Aeroanchored.Balloon_winch_GER1 de 29244.30 15856.53 0.00 /hstart 20/hend 200
Static82 Artillery.Krupp_L2H43_Protze_Flak38 de 29246.27 15871.57 0.00 /timeout 0/radius_hide 0
...
При достижении в "Битве" некого условия, нужно все эти объекты из миссии уничтожить и загрузить заново (из той же миссии). Объекты при этом могут быть в трех состояниях. Целая зенитка, подбитая (дымящаяся зенитка) и уже удаленная зенитка. То есть пустое место. Аэростаты пока в двух состояниях. Целые и подбитые (удалять подбитые еще не научился).
Как удалить с карты все эти объекты разом? И зенитки и аэростаты.
Находил кое-какие примеры, но чет мне это показалось очень сложным. :(
Тем более, что у меня там не группы. А просто отдельные объекты, стоящие на охране ВПП.
-
Re: Полный редактор и скрипты.
В примерах naryv загружает и удаляет зенитки в определенном радиусе от маркера.
Видимо проще загружать отдельную подмиссию только с этими объектами и удалять соответственно только объекты этой подмиссии. Примеры скриптов actor destroy есть в архиве (папка _actors destroy ).
-
Re: Полный редактор и скрипты.
Да нет же! Там все не то. Там по событию OnActorCreated на каждого вновь созданного актора заводится свой личный таймер. Этот свой личный уникальный таймер помнит каждого своего актора по его имени (ну, или еще как-то там). Когда подходит срок кончины актора, то таймер, постоянно зная и не забывая своего родного актора, убивает его.
Вот код из тех примеров:
Код:
public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
base.OnActorCreated(missionNumber, shortName, actor);
//Ground objects will die after 55 min when counted from their birth
if (actor is AiGroundActor)
Timeout(3300, () =>
{
if (actor != null)
{ (actor as AiGroundActor).Destroy(); }
}
);
}
У меня в миссии вообще нет таймеров. Мне это не нужно и не интересно. Созданные мною объекты - "Артиллерия", существуют бесконечно долго. Скажем, в ходе битвы половина будет уничтожена, другая половина останется. Сработает некое условие. По моей задумке и сценарию, этим условием будет являться убиение шести вражеских зениток на любых ВПП противника. Как только это будет сделано, условие срабатывает и подмиссия, ответственная за загрузку зениток на ВПП, загружает в виде бонуса, для выигрывавшей стороны, новые зенитки на всех дружественных ВПП. Но прежде, чем загрузить новые зенитки, нужно убить все оставшиеся старые зенитки (которые еще не были подбиты или которые еще только догорают). Ну, чтобы не было каши. Чтобы одна зенитка не становилась на другую зенитку.
От Small_Bee есть замечательный пример чистки всего того, что есть в миссиях циклами "foreach".
Пример...
Сканируем все существующие армии в битве:
foreach (int army in GamePlay.gpArmies())
В тело этого основного цикла вкладываем цикл по перебору всех существующий групп в этих армиях:
foreach (AiAirGroup group in airGroups)
И уже в тело этого цикла вкладываем последний цикл по перебору всех акторов в группе:
foreach (AiActor actor in group.GetItems())
И все бы хорошо. Но у меня в миссии нет групп!!! У меня есть отдельно стоящие объекты типа "Артиллерия". Которые группами не являются. Вот я и не пойму, как мне циклом, или не циклом, перебрать все эти объекты и удалить их.
Цитата:
Сообщение от
-atas-
...Видимо проще загружать отдельную подмиссию только с этими объектами...
Разумеется так и делаю. Одна подмиссия грузит все Синие зенитки на всех ВПП Синих, другая грузит Красные...
Цитата:
Сообщение от
-atas-
...и удалять соответственно только объекты этой подмиссии.
Как это сделать???!!! :)
-
Re: Полный редактор и скрипты.
Акторов без групп надо только запоминать. Или если ты точно помнишь их имена и номера миссий, в которых они загружены. Никаким перебором ты их не найдешь.
Т.е. по OnActorCreated и если группа null, запоминаешь их полные имена где-то в списке. Перед загрузкой миссии смотришь след. номер миссии, е если параметре к OnActorCreated будет этот номер - значит твой клиент. Соотв., если хочешь их удалить, пробегаешься по списку, и которые еще живы, убираешь.
В "Морском льве" этим рулит спец. класс. И у него есть методы (грубо) SetMisFileName(), Load() и Unload() (Перед вызовом Load к примеру он сам вызывает Unload и прибирается). Т.е. достаточно рулить только экземпляром класса, вся механика скрыта в нем, очень удобно. Там еще куча всего вроде отложенной загрузки, нотификации о том, что все акторы померли и т.д. Т.е. можно дополнять дальше соотв. своих требованиям.
В твоем случае можно сделать что-то вроде класса Батарея, экземпляры которого сами будут следить за состоянием своих орудий и предоставлять информацию о них вовне, Батареи объединить скажем в Дивизион, который смотрит за состоянием батарей. Так мы уходим от необходимости следить за каждой мордой отдельно, а разговаривать уже непосредственно как бы с "командирами" верхнего уровня. И микроменеджмент батарей и дивизионов переложить на них и младших, и не беспокоится об этом.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Да нет же! Там все не то. Там по событию OnActorCreated на каждого вновь созданного актора заводится свой личный таймер.
Я же не говорил, что это нужно OnActorCreated делать. Можно и onTrigger. (В миссиях naryv зенитки по триггеру захвата маркера удаляются)
А перебирать можно не только группы, но и акторов (поискать в примерах foreach actor in ... или типа того) емнип.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
...Т.е. по OnActorCreated и если группа null, запоминаешь их полные имена где-то в списке. Перед загрузкой миссии смотришь след. номер миссии, е если параметре к OnActorCreated будет этот номер - значит твой клиент. Соотв., если хочешь их удалить, пробегаешься по списку, и которые еще живы, убираешь.
Эх! Мне бы все тоже самое, только с небольшим примером. Номер миссии - это я понял. А какое имя запоминать? "Actor.Name()"? И потом, когда я запомню это самое строковое имя и номер миссии, как узнать, какой это будет потом "actor"? Ведь функция Destroy(), как я понял, работает только зная сам объект "actor", а не его строковое имя в миссии. Если я не прав, то очень бы хотел знать, как зная только строковое имя актора и номер мисси, можно применить функцию Destroy(). Ни в одном примере я не смог найти ничего, кроме такого написания:
(actor as AiGroundActor).Destroy();
Очень бы хотелось написать вот так: "Static4".Destroy(); Но это, естественно, работать не будет.
Какой список имен создавать? Некий двумерный массив или может быть справочник "Dictionary". Или еще что-то, более удобное?
Цитата:
Сообщение от
Small_Bee
...В твоем случае можно сделать что-то вроде класса Батарея...
Ой, нет! Спасибо! :)
Это точно не мой случай. В ООП я не секу совершенно. Не тот уровень подготовки. А с этим C# (с его невероятно сложным и малопонятным синтаксисом) вообще столкнулся впервые.
Цитата:
Сообщение от
-atas-
...А перебирать можно не только группы, но и акторов (поискать в примерах foreach actor in ... или типа того)...
Неа! Бесполезно. Не смог найти. Похоже, что этого и нет вовсе. :(
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
Перед загрузкой миссии смотришь след. номер миссии
А как его узнать и запомнить? Например, у меня в Степях может одновременно крутиться 3 одинаковых подмиссии с соответственно одинаковыми именами триггера. Мне нужно проверять триггер какой из подмиссии сработал, чтобы считать счет для каждой подмиссии (чтобы не путаться). OnTrigger я могу перебрать все активные миссии и проверить, if (missionnumber == x) но вот где получить х? Самому вручную считать при загрузке каждой подмиссии x = ++ ? Но возможно missionnumber, который присутствует в OnTrigger в каком-то своем внутреннем формате считается?
Т.е. другими словами missionnumber из OnTrigger - это некая внутренняя вещь БзБ или я могу эти номера сам назначать перед загрузкой каждой подмиссии?
--- Добавлено ---
Цитата:
Сообщение от
SlavikSG
Неа! Бесполезно. Не смог найти. Похоже, что этого и нет вовсе. :(
В cross_roundel миссии naryv:
Код:
foreach (AiGroundGroup gg in GamePlay.gpGroundGroups(army))
{
if (gg != null)
if (gg.Pos().distance(ref AirportPos) < 2000)
{
string triggerName = gg.Name().Substring(0,gg.Name().IndexOf(":"))+":"+markerNum.ToString()+"_" + army .ToString()+ "_attack";
AiTrigger trigger = GamePlay.gpGetTrigger(triggerName);
if (trigger != null) trigger.Enable = false;
foreach (AiActor ggActor in gg.GetItems())
{ if ((ggActor as AiGroundActor) != null)
(ggActor as AiGroundActor).Destroy();
}
}
}
В других его миссиях тоже есть при похожих обстоятельствах но в других видах (отдельно для артиллерии и танков емнип).
edit
Там еще 2я часть интересная, как раз про артиллерию с перебором статиков.
Код:
private void DestroyEnemyAtCaptured(int markerNum, int army)
{
Point3d AirportPos;
AirportPos.x = MissionMarkers[markerNum].x;
AirportPos.y = MissionMarkers[markerNum].y;
AirportPos.z = 1;
foreach (AiGroundGroup gg in GamePlay.gpGroundGroups(army))
{
if (gg != null)
if (gg.Pos().distance(ref AirportPos) < 2000)
{
string triggerName = gg.Name().Substring(0,gg.Name().IndexOf(":"))+":"+markerNum.ToString()+"_" + army .ToString()+ "_attack";
AiTrigger trigger = GamePlay.gpGetTrigger(triggerName);
if (trigger != null) trigger.Enable = false;
foreach (AiActor ggActor in gg.GetItems())
{ if ((ggActor as AiGroundActor) != null)
(ggActor as AiGroundActor).Destroy();
}
}
}
for (int i = 0; i < MissionsCount; i++)
{
AiGroundActor curActor;
for (int j = 0; j < 10; j++)
{
string nameActor = i.ToString() + ":Static" + j.ToString();
curActor = GamePlay.gpActorByName(nameActor) as AiGroundActor;
if (curActor != null)
{
if ( (curActor.Army() == army) &&
(curActor.Pos().distance(ref AirportPos) < 2000) &&
((curActor.Type() == AiGroundActorType.AAGun)||(curActor.Type() == AiGroundActorType.Artillery) )
)
{
curActor.Destroy();
}
}
}
}
}
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Эх! Мне бы все тоже самое, только с небольшим примером. Номер миссии - это я понял. А какое имя запоминать? "Actor.Name()"? И потом, когда я запомню это самое строковое имя и номер миссии, как узнать, какой это будет потом "actor"? Ведь функция Destroy(), как я понял, работает только зная сам объект "actor", а не его строковое имя в миссии. Если я не прав, то очень бы хотел знать, как зная только строковое имя актора и номер мисси, можно применить функцию Destroy(). Ни в одном примере я не смог найти ничего, кроме такого написания:
(actor as AiGroundActor).Destroy();
Очень бы хотелось написать вот так: "Static4".Destroy(); Но это, естественно, работать не будет.
Какой список имен создавать? Некий двумерный массив или может быть справочник "Dictionary". Или еще что-то, более удобное?
Ой, нет! Спасибо! :)
Это точно не мой случай. В ООП я не секу совершенно. Не тот уровень подготовки. А с этим C# (с его невероятно сложным и малопонятным синтаксисом) вообще столкнулся впервые.
Неа! Бесполезно. Не смог найти. Похоже, что этого и нет вовсе. :(
Если не ошибаюсь, есть метод GamePlay.gp(Get?)ActorByName(...), вроде так. Который позволяет получить актора по его полному имени, или вернет null, если актор не найден, соответственно после можно применить Destroy(). Напоминаю, полное имя актора выглядит как "номер миссии":"короткое имя". Для жонглирования именами используется стат. класс ActorName. Например, почти каждый метод возвращает номер миссии и короткое имя, можно с помощью ActorName получить из них правильно полное имя. AiActor.Name() возвращает полное имя.
Список какой будет удобнее, конечно.
Знаний ООП хватит и базовых, литературы масса. Синтаксис C# весьма несложный, тем более почти один в один с плюсов или PHP.
--- Добавлено ---
Цитата:
Сообщение от
-atas-
А как его узнать и запомнить? Например, у меня в Степях может одновременно крутиться 3 одинаковых подмиссии с соответственно одинаковыми именами триггера. Мне нужно проверять триггер какой из подмиссии сработал, чтобы считать счет для каждой подмиссии (чтобы не путаться). OnTrigger я могу перебрать все активные миссии и проверить, if (missionnumber == x) но вот где получить х? Самому вручную считать при загрузке каждой подмиссии x = ++ ? Но возможно missionnumber, который присутствует в OnTrigger в каком-то своем внутреннем формате считается?
Т.е. другими словами missionnumber из OnTrigger - это некая внутренняя вещь БзБ или я могу эти номера сам назначать перед загрузкой каждой подмиссии?
Нет, назначать не можешь, но есть метод NextMissionNumber(), правда где именно (миссия, Battle или gamePlay) не помню. Опять же, отсылка к лёве, там это есть.
-
Re: Полный редактор и скрипты.
Да нет же! Это опять же поиск в группе:
foreach (AiGroundGroup gg in GamePlay.gpGroundGroups(army))
...
foreach (AiActor ggActor in gg.GetItems())
У меня нет групп.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
-atas-
edit
Там еще 2я часть интересная, как раз про артиллерию с перебором статиков.
Тут некая эмуляция перебора, исходя из предположения, что имена статиков руками не менялись. Т.е. мы последовательно перебираем диапазон возможных имен, если кто с таким именем попадается, то работаем с ним. Т.е. нам придется сделать M*N итераций, где M - количество миссий, N - макс. кол-во статиков в миссии. Даже не кол-во, а макс. номер статика. Например, если у нас будет два статика - Static0 и Static99, N будет не 2, а 100.
2 SlavikSG
Вот кстати и получение актора по имени
curActor = GamePlay.gpActorByName(nameActor) as AiGroundActor;
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Да нет же! Это опять же поиск в группе:
foreach (AiGroundGroup gg in GamePlay.gpGroundGroups(army))
...
foreach (AiActor ggActor in gg.GetItems())
У меня нет групп.
Если я правильно понимаю, то каждая зенитка - это группа, состоящая из одного актора, т.е. группы есть у всех, у кого есть акторы. Иначе откуда у naryv могут взяться группы зениток???
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
-atas-
Если я правильно понимаю, то каждая зенитка - это группа, состоящая из одного актора, т.е. группы есть у всех, у кого есть акторы. Иначе откуда у naryv могут взяться группы зениток???
Нет, зенитка\артиллерия - это актор без группы. У Ильи соотв. также нет групп зениток, он перебирает поименно всех возможных статиков, если статик окажется зениткой или пушкой, прибивает.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
... Вот кстати и получение актора по имени
curActor = GamePlay.gpActorByName(nameActor) as AiGroundActor;
Ага. Я уже нашел в примерах. Это наконец-то сработало. Большое спасибо! :)
Bbb = GamePlay.gpActorByName(ActorName.Full(2, "Static4")); //Где "двойка" это номер миссии
Теперь начну ковыряться дальше...
Цитата:
Сообщение от
-atas-
Если я правильно понимаю, то каждая зенитка - это группа, состоящая из одного актора...
Я понял, о чем ты. Но у меня не так.
P.S.
Не знаю, вопрос в тему или нет. А правда, что у зениток, находящихся в группе, заканчиваются патроны? :)
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Ага. Я уже нашел в примерах. Это наконец-то сработало. Большое спасибо! :)
Bbb = GamePlay.gpActorByName(ActorName.Full(2, "Static4")); //Где "двойка" это номер миссии
Теперь начну ковыряться дальше...
Я понял, о чем ты. Но у меня не так.
P.S.
Не знаю, вопрос в тему или нет. А правда, что у зениток, находящихся в группе, заканчиваются патроны? :)
Да. Интерфейсов для перезарядки пока нет, т.е. надо удалить старую и поставить новую.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
Да. Интерфейсов для перезарядки пока нет, т.е. надо удалить старую и поставить новую.
Ага. Видимо я поэтому и уперся рогом именно в тип наземки "Артиллерия", а не "Броня". :)
-
Re: Полный редактор и скрипты.
В ходе работы над скриптом, возник вопрос такого плана. Имеем событие убиения зенитки. После чего стразу удаляем ее трупик. Пишем такой код:
Код:
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
if (actor is AiGroundActor)
{
(actor as AiGroundActor).Destroy();
Sss("Удалили красную зену: " + actor.Name());
}
}
и получаем стопроцентную ошибку. :(
Но если пишем все в точности так же, но делаем задержку в одну секунду, то никакой ошибки не возникает.
Код:
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
if (actor is AiGroundActor)
{
Timeout(1, () =>
{
(actor as AiGroundActor).Destroy();
Sss("Удалили красную зену: " + actor.Name());
});
}
}
Почему такое происходит??? Получается, что нужно всегда делать задержку?
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
и получаем стопроцентную ошибку. :(
Небольшое дополнение...
В логе сервера пишется ошибка, но зенитка все равно исправно удаляется.
(это я выяснил уже потом)
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
В ходе работы над скриптом, возник вопрос такого плана. Имеем событие убиения зенитки. После чего стразу удаляем ее трупик. Пишем такой код:
Код:
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
if (actor is AiGroundActor)
{
(actor as AiGroundActor).Destroy();
Sss("Удалили красную зену: " + actor.Name());
}
}
и получаем стопроцентную ошибку. :(
Но если пишем все в точности так же, но делаем задержку в одну секунду, то никакой ошибки не возникает.
Код:
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
if (actor is AiGroundActor)
{
Timeout(1, () =>
{
(actor as AiGroundActor).Destroy();
Sss("Удалили красную зену: " + actor.Name());
});
}
}
Почему такое происходит???
Вы уничтожаете объект (actor as AiGroundActor).Destroy(); а затем - пытаетесь получить его имя - actor.Name(). Если актор уже успел задестроиться, то Вы пытаетесь получить .Name() от null-a, что даст ошибку естественно. С таймаутом дестрой может позже произойти поэтому ошибки не будет.
Можно сделать что-то типа этого -
Код:
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
if (actor is AiGroundActor)
{
string actorName = actor.Name();
(actor as AiGroundActor).Destroy();
if (actor == null)
Sss("Удалили красную зену: " + actorName);
}
}
-
Re: Полный редактор и скрипты.
Не-не-не!!! Сори!
Я этой функцией вывода вспомогательного сообщения, только ввел вас в заблуждение.
Все! Забыли про Sss("Удалили красную зену: " + actorName); Дело вовсе не в этом. Ошибка есть так или иначе. Вот код без этой функции и ошибка все равно возникает:
Код:
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
if (actor is AiGroundActor)
{
(actor as AiGroundActor).Destroy();
}
}
Проверил только что еще раз. Ошибка есть. И нет ошибки, если проделать все тоже самое, но с секундной задержкой.
Но подчеркиваю: И в том и в этом случае, зенитка все равно нормально удаляется.
Ошибка возникает такая:
Код:
=================================================
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
в C73nDcVHkfNlG1HRmmb.RW57KCVWohHyXJ5krUt.ydxsYS7apyu(d19kQTbEvXhjHykyf8d , dICXoRXk7y7vkkUvR4v , Int16 , Boolean )
в 12oB5s7LiQTBW7EtP2V.n61Vjl7SllEshhqKbYQ.kHlBq45JnvX(oXNPnT8Hh3UKJa6ZZy , SUsxEiF3QjXTYkAujT1 , B75N63VkDk3IVOC1G3Q , GPYJGEs07NMqUYFIJRN , Double& )
в C73nDcVHkfNlG1HRmmb.RW57KCVWohHyXJ5krUt.msgShot(SUsxEiF3QjXTYkAujT1 )
в H9k668FBsuD6ndx8Z0w.SUsxEiF3QjXTYkAujT1.P0colRfLS3u(SUsxEiF3QjXTYkAujT1 )
в H9k668FBsuD6ndx8Z0w.SUsxEiF3QjXTYkAujT1.X7cYOeKBYyql3jthiEO0(Object )
в H9k668FBsuD6ndx8Z0w.SUsxEiF3QjXTYkAujT1.Tm6oln8qMcy(d19kQTbEvXhjHykyf8d , Tujx1nWZkdCL5iBIZk , String , Point3d& , Vector3d& , Double , Double , b5X4V3c4exFtE9L5FjX , Double , bV5YXhceO4t4hjKDLyi )
в iTQ2F3BmBVt9SCk6mLU.ZwK9QMBBEsmk1BR0vEh.cujSBu15Yef(Tujx1nWZkdCL5iBIZk , String )
в ni37tVPHruIq9NlxXSS.U44P7gPWjvHAMLK3Rv5.pkis5BedngrRoylBJHRX(Object , Object , Object )
в ni37tVPHruIq9NlxXSS.U44P7gPWjvHAMLK3Rv5.QkEsNixkSaq(Object )
в PDEYCdwa2J4QMrF1lcD.d4vV2vwCQi0a584sPXx.JBeVQdP174(Object )
=================================================
Еще один вопрос Зенитка принадлежит к "AiGroundActor". А к чему принадлежит аэростат-лебедка этого типа: "Aeroanchored.Balloon_winch_GER1"? (это название из файла-миссии)
Я это к тому спрашиваю, что тоже, как и зенитку, хотел бы его удалять по факту попадания в него. Как это сделать? Ведь такой код для аэростата тут уже явно не сработает:
if (actor is AiGroundActor)
{
(actor as AiGroundActor).Destroy();
}
-
Re: Полный редактор и скрипты.
Вот так всегда. Пропали все гуру на самом интересном месте. :(
Алеее!! Люююди! Есть, кто живой?
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Вот так всегда. Пропали все гуру на самом интересном месте. :(
Алеее!! Люююди! Есть, кто живой?
По поводу ошибки не совсем ясно, почему. Да и смысл удаления трупика сразу же от меня ускользает. Т.е. я в нее выстрелил, а она испарилась.
По поводу баллона говорилось - их ты никак в скрипте не увидишь и ничего с ними не сделаешь. Выше, а так-же в темах Вопросы, Морской лев, Обсуждение миссий и т.д. этот момент подчеркивался неоднократно.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
По поводу ошибки не совсем ясно, почему. Да и смысл удаления трупика сразу же от меня ускользает. Т.е. я в нее выстрелил, а она испарилась...
Да, конечно. Зенитка должна погореть, подымиться. Это без сомнений. :)
Я поясню. Смысл не такой. Смысл в том, что начинаем удалять трупики, как только будет уничтожена шестая зенитка. Сразу все очищаем и ставим новые.
А так, вообще, вопрос отпал. Пока читал твой пост, меня осенило. Поставил секундную задержку в другую часть кода и у меня все получилось. Хотя да, ты прав. Смысл ошибки действительно непонятен и она по прежнему имеет место быть.
Цитата:
Сообщение от
Small_Bee
...По поводу баллона говорилось - их ты никак в скрипте не увидишь и ничего с ними не сделаешь. Выше, а так-же в темах Вопросы, Морской лев, Обсуждение миссий и т.д. этот момент подчеркивался неоднократно.
Спасибо за пояснение. Я не заметил этого момента. Но тогда вопрос хотелось бы поставить несколько иначе. Какой объект, типа "Аэростат", можно было бы отслеживать в миссии? Уж больно хочется их заюзать. Возможно как-то обойти это ограничение? Без них как-то скучновато будет в мисси. А получается, что один раз поставил, их взорвали, и ничего с этим уже не поделаешь. Получается, что загрузить я их могу, а удалить нет. :(
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Спасибо за пояснение. Я не заметил этого момента. Но тогда вопрос хотелось бы поставить несколько иначе. Какой объект, типа "Аэростат", можно было бы отслеживать в миссии? Уж больно хочется их заюзать. Возможно как-то обойти это ограничение? Без них как-то скучновато будет в мисси. А получается, что один раз поставил, их взорвали, и ничего с этим уже не поделаешь. Получается, что загрузить я их могу, а удалить нет. :(
Скриптом - никак. Это печально, но факт. Сначала даже пушки нельзя было отслеживать, должны вроде добавить аналогичный функционал и к другим статикам, но когда именно, неизвестно.
Обходной путь может быть в установке триггера на уничтожение наземки в районе. Но там надо учитывать несколько моментов. Казалось бы, поставь мотоцикл статический, сверху триггер и требование 100% уничтожения. Мотоцикл убили, триггер сработал. Ан нет. Есть баг, при котором при оценке кол-ва объектов триггер считает сам мотоцикл и те две физиономии, что в нем сидят, но при уничтожении - только мотоцикл, т.е. проценты будут - 33.3333- и триггер никогда не сработает. Это должно быть в след. патче поправлено. И второй момент - триггер, при оценке статиков что в его радиус попадают, используют не координаты, а т.н. сферу первичной коллизии (если не ошибаюсь) которой этот статик окружен. Таким образом, если поставить вышку высотой скажем метров 30, то любой триггер, который зайдет радиусом в радиус 30 метров от вышки (грубо), будет считать ее своей. Третий момент - триггеры не учитывают объекты с нейтральной армией. Т.е. домики ты таким образом тоже не отследишь (те которые в разделе Здания - у них нельзя выставить армию).
-
Re: Полный редактор и скрипты.
Текс, хорошо. Это я все понял. Пусть тригер. Меня это устроит. Но! Я не пойму, как применить Destroy() к такому объекту, как "Aэростат". Как написать код уничтожению аэростата? Ведь такой код не пашет, применительно к нему:
Код:
if (actor is AiGroundActor)
{
(actor as AiGroundActor).Destroy();
}
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Текс, хорошо. Это я все понял. Пусть тригер. Меня это устроит. Но! Я не пойму, как применить Destroy() к такому объекту, как "Aэростат". Как написать код уничтожению аэростата? Ведь такой код не пашет, применительно к нему:
Код:
if (actor is AiGroundActor)
{
(actor as AiGroundActor).Destroy();
}
Конечно не работает, уничтожения аэростата не вызывает никаких методов в миссии, конечно нельзя применить Destroy() когда нету даже ссылки на объект. )))
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
Конечно не работает, уничтожения аэростата не вызывает никаких методов в миссии, конечно нельзя применить Destroy() когда нету даже ссылки на объект. )))
Я не был бы так настойчив, если бы не был уверен в обратном. Проверял это дело раньше. Проверил и еще раз. Событие на убиение аэростата происходит! Гружу одной миссией шесть синих зениток в ряд. Другой миссией гружу напротив два красных аэростата. И пишу такой код:
Код:
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
Sss("Был подбит аэростат армии :" + actor.Army().ToString());
Sss("Хеш подбитого аэростата :" + actor.GetHashCode().ToString());
Sss("Имя подбитого аэростата :" + actor.Name());
}
И в логе сервера пишется это:
Server: Был подбит аэростат армии :1
Server: Хеш подбитого аэростата :60779388
Server: Имя подбитого аэростата :NONAME
Server: Был подбит аэростат армии :1
Server: Хеш подбитого аэростата :2922015
Server: Имя подбитого аэростата :NONAME
Определяется и "Хеш" и "Армия". А вот остальное ничего не пашет. В том числе и имя, заданное в файле-миссии, не определяется. А вот само событие срабатывает четко и неизменно.
Ладно, наверное с этим пока точно ничего не поделаешь. Буду спавнить аэростаты просто в начале миссии. Где-нибудь не рядом с зенитками, а подальше. Так, чтобы глаз радовали, и если подобьют, чтобы трупики их (не убирающиеся) не сильно мешались.
Имею еще один каверзный вопрос:
Есть событие появления в миссии объектов. Название ему OnActorCreated. Естественно, срабатывает оно на все подряд. При этом срабатывании я начинаю заполнять, ранее созданные два словаря: _Zenitki_Red_ и _Zenitki_Blue_. Заполняю я их только нужными мне объектами. А именно зенитками. Все остальное игнорируется. Пишу такой код:
Код:
public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
base.OnActorCreated(missionNumber, shortName, actor);
Timeout(1, () =>
{
//Определяем имя загружаемого объекта
Zena = (actor as AiCart).InternalTypeName().ToString();
//Если миссия не является стартово-загрузочной и этот объект принадлежит
// армии красных и имя ему "bob:Artillery.Krupp_L2H43_Protze_Flak38", то...
if (missionNumber != 0 && actor.Army() == 1 && Zena == "bob:Artillery.Krupp_L2H43_Protze_Flak38")
{
_Zenitki_Red_.Add(shortName, missionNumber); //добавляем в справочник красных очередную новую запись
}
//Если миссия не является стартово-загрузочной и этот объект принадлежит
// армии синих и имя ему "bob:Artillery.Krupp_L2H43_Protze_Flak38", то...
if (missionNumber != 0 && actor.Army() == 2 && Zena == "bob:Artillery.Krupp_L2H43_Protze_Flak38")
{
_Zenitki_Blue_.Add(shortName, missionNumber); //добавляем в справочник синих очередную новую запись
}
});
}
Опять же, как и несколько постов ранее, получается, что нужно нужно ОБЯЗАТЕЛЬНО вводить задержку Timeout. Если ее не вводить, то все отлично пашет и так, но в логе сервера неизменно возникает ошибка, как только я пытаюсь выполнить эту часть кода: Zena = (actor as AiCart).InternalTypeName().ToString();. Повторюсь... Это все замечательно пашет и без задержки Timeout.
Непонятки эти, происходящие в событиях мисси, меня сильно напрягают. Что при удалении объекта, нужно делать задержку, что при его создании считывать атрибуты опять же нужно с задержкой. Все это как-то сумбурно... :(
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Server: Имя подбитого аэростата :NONAME
Да, немного ошибся, но сути не меняет. Выделенное - Ключевой момент. К какому классу относятся эти нонеймы или какие интерфейсы реализовывают я так и не понял. Т.е. имя конечно есть, но оно то ли обфускатором обработано, то ли еще как, чего с ними делать, не представляю. Как только не крутил. Поэтому такие нонеймы пропускаю. Собственно почему и сказал, что метод не вызывается - тушение нонеймов это у меня в первую очередь. )
--- Добавлено ---
Цитата:
Сообщение от
SlavikSG
Опять же, как и несколько постов ранее, получается, что нужно нужно ОБЯЗАТЕЛЬНО вводить задержку Timeout. Если ее не вводить, то все отлично пашет и так, но в логе сервера неизменно возникает ошибка, как только я пытаюсь выполнить эту часть кода: Zena = (actor as AiCart).InternalTypeName().ToString();. Повторюсь... Это все замечательно пашет и без задержки Timeout.
Непонятки эти, происходящие в событиях мисси, меня сильно напрягают. Что при удалении объекта, нужно делать задержку, что при его создании считывать атрибуты опять же нужно с задержкой. Все это как-то сумбурно... :(
Мы на самом деле не знаем, что конкретно делает дестрой. И получаем мы интерфейс, а истинный класс, который за ним скрыт и что как он делает мы не знаем, и согласно принципам ООП и не должны. )
Вполне возможно, что на момент вызова метода какие-то поля еще не инициализированы.
ЫЫЫ слушай у меня тут эврика сияет, а DamagerScore там заполнен? И можно ли Pos() получить? И глянь плиз где именно Army() определен, я сам сейчас не посмотрю, а очень хочется )
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Не-не-не!!! Сори!
Я этой функцией вывода вспомогательного сообщения, только ввел вас в заблуждение.
Все! Забыли про
Sss("Удалили красную зену: " + actorName); Дело вовсе не в этом. Ошибка есть так или иначе. Вот код без этой функции и ошибка все равно возникает:
Код:
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
if (actor is AiGroundActor)
{
(actor as AiGroundActor).Destroy();
}
}
Проверил только что еще раз. Ошибка есть. И нет ошибки, если проделать все тоже самое, но с секундной задержкой.
Но подчеркиваю:
И в том и в этом случае, зенитка все равно нормально удаляется.
Сорри, я сейчас в отпуске, поэтому только набегами и проверить что да как не могу. По дестрою умершего объекта до меня только сейчас дошло - во время actorDie на объект цепляются всякие дымы, огни и пр. эффекты, которые какое-то время инициализируются и через какое-то время должны прекратиться, если такой умерший объект задестроить - вылезет NullReferenceException при попытке системой обработать эти эффекты. Плюс, убитые пушки, например, при убийстве принимают "дохлый вид" не заменой на модельку дохлой, а приведением живой к дохлому виду - темнеет, опускает ствол и т.д., соответственно, игра пытается довернуть ствол в "мёртвое состояние " а объект скриптом уже задестроен - вот NullReferenceExceptionи выскакивает.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
...ЫЫЫ слушай у меня тут эврика сияет, а DamagerScore там заполнен? И можно ли Pos() получить? И глянь плиз где именно Army() определен, я сам сейчас не посмотрю, а очень хочется )
С этим параметром я еще не работал, а так, вообще-то, там что-то заполняется.
Чисто наобум глянул. Увидел это:
damages.Count равен: 1
ddamages[0].initiator.Actor.Name() равен: 2:Static2
damages[0].initiator.Person.Name() равен: NONAME
...ну, там много чего еще есть. Только больше, мне кажется, там инфы не "кого" убили, а "кто" убил. В любом случае, надеюсь на твою гениальность. А вдруг, что-то можно родить? В смысле убить трупик... :)
Цитата:
Сообщение от
naryv
...соответственно, игра пытается довернуть ствол в "мёртвое состояние " а объект скриптом уже задестроен - вот NullReferenceException и выскакивает.
Ясно. Я догадывался... Это было видно еще по тому, как "хеш" объекта меняется. Ну, мне главное, чтобы я был уверен, что скрипт пишу правильно и чтобы ошибка в логе сервера не приводила к утечке памяти или к крушению сервака. А в остальном, на это можно и забить. :)
P.S.
Давай уже выходи из отпуска скорее. Летом догуляешь. Кто ж в такое время отдыхает? Погода - жесть!!! Ггг! :)
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
С этим параметром я еще не работал, а так, вообще-то, там что-то заполняется.
Чисто наобум глянул. Увидел это:
damages.Count равен: 1
ddamages[0].initiator.Actor.Name() равен: 2:Static2
damages[0].initiator.Person.Name() равен: NONAME
...ну, там много чего еще есть. Только больше, мне кажется, там инфы не "кого" убили, а "кто" убил. В любом случае, надеюсь на твою гениальность. А вдруг, что-то можно родить? В смысле убить трупик... :)
Это понятно, что там тот, кто убил. Значит уже хорошо, бобрам статики считать можно... Осталось каким то образом разрулить, кого убили. Если можно получить позицию через Pos(), то в принципе, зная наперед, что мы туда поставили, можно определится, кого убили. Примерно так.
-
Re: Полный редактор и скрипты.
Ага. Ясно.
Но я так понимаю, это для статистики полезно будет, но никак не для определения истинного "actor"-а убиенного объекта, с последующим его удалением из миссии. Верно?
Кстати, а есть уже у кого-то рабочий начальный вариант скрипа статистики? Я бы с удовольствием глянул краем глаза на это дело. :)
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Ага. Ясно.
Но я так понимаю, это для статистики полезно будет, но никак не для определения истинного "actor"-а убиенного объекта, с последующим его удалением из миссии. Верно?
Кстати, а есть уже у кого-то рабочий начальный вариант скрипа статистики? Я бы с удовольствием глянул краем глаза на это дело. :)
Примитивные варианты где-то есть, скрипят вроде. На форуме покопаться. Более продвинутый в работе, сам плюс бд готовы процентов на 95, вебморда процентов на 5% )
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
...Более продвинутый в работе, сам плюс бд готовы процентов на 95.
БД на MySQL или что-то иное?
Да, нужно поискать примеры. Без понятия, как C# общается с базами данных. Немного ваял это дело на PHP, а вот в этом деле - полный ноль. Видимо придется плотнее изучать C#. Но начать хотелось бы все же с готовых примеров.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
БД на MySQL или что-то иное?
Да, нужно поискать примеры. Без понятия, как C# общается с базами данных. Немного ваял это дело на PHP, а вот в этом деле - полный ноль. Видимо придется плотнее изучать C#. Но начать хотелось бы все же с готовых примеров.
Вообще для MySQL есть провайдер .NET, можно у них на оффсайте забрать. А если нет, так ничто не мешает сделать что то вроде REST службы на PHP и юзать на здоровье. MySQL выбрана как самая доступная и простая база, но в принципе никто не мешает заменить на другую базу или вообще записи в файл, возможность переключения заложена.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
Вообще для MySQL есть провайдер .NET, можно у них на оффсайте забрать. А если нет, так ничто не мешает сделать что то вроде REST службы на PHP и юзать на здоровье...
Эх! Не знаю я пока ни того, ни другого. :(
Ну, да ладно. Займусь этим чуть позже.
Вопрос:
Имеется статический объект - "Минный тральщик". Его подбивают. Он тонет и пропадает из битвы бесследно. Нужно ли убирать его трупик, (который теоретически должен лежать на дне моря), перед загрузкой нового Минного тральщика?
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Ясно. Я догадывался... Это было видно еще по тому, как "хеш" объекта меняется. Ну, мне главное, чтобы я был уверен, что скрипт пишу правильно и чтобы ошибка в логе сервера не приводила к утечке памяти или к крушению сервака. А в остальном, на это можно и забить. :)
в принципе к крашам или утечке памяти такие ситуации не должны приводить, но вообще, лучше избегать таких ситуаций.
Цитата:
Сообщение от
SlavikSG
P.S.
Давай уже выходи из отпуска скорее. Летом догуляешь. Кто ж в такое время отдыхает? Погода - жесть!!! Ггг! :)
ну у меня " по семейным обстоятельствам" отпуск :).
Цитата:
Сообщение от
SlavikSG
Вопрос:
Имеется статический объект - "Минный тральщик". Его подбивают. Он тонет и пропадает из битвы бесследно. Нужно ли убирать его трупик, (который теоретически должен лежать на дне моря), перед загрузкой нового Минного тральщика?
Можно и убрать, он не бесследно пропадает, он "тонет" :)
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
naryv
...но вообще, лучше избегать таких ситуаций.
Ага. Уже ввел задержку на 1 секунду. Ошибка пропала.
Цитата:
Сообщение от
naryv
... Можно и убрать, он не бесследно пропадает, он "тонет" :)
Убираю. Надеюсь правильно. И на дне не будет скапливаться груда ржавеющих трупиков. :)
Такой вопрос:
Правильно ли я мыслю, что для того, чтобы сделать респавн на каждый одиночный статический объект в битве (зенитка, корабль) нужно создавать свою отдельную миссию на этот объект? Иными словами; объект подбили, затем, по таймеру мы убираем его трупик, и так же по таймеру, или еще по какому-то другому условию, загружаем миссию с этим объектом снова. Верно я понимаю этот процесс? Или быть может есть какой-то другой, более простой способ подзагрузки, тех или иных, одиночных объектов? А то получается, что сколько в битве присутствует одиночных статических объектов, столько и должно быть вспомогательных миссий, для загрузки этих объектов. В старом Ил-2 с этим было все просто. Задал время респавна объектов и забыл про это.
Вопрос по статистике:
Цитата:
Сообщение от
Small_Bee
Примитивные варианты где-то есть, скрипят вроде. На форуме покопаться...
Поискал по форуму примеры скриптов статистики. Ничего не смог найти. Пусто. В том числе пусто и в архиве примеров. Искал по таким словам, как:
SqlClient
SqlConnection
Может не так искал? Единственное, что нашел - это ссылку на рабочую статистику сервера Репки2: http://r2.repka.su/ и в общем-то и все. А очень бы хотелось глянуть несколько примеров того, как это все делается.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Вопрос по статистике:
Поискал по форуму примеры скриптов статистики. Ничего не смог найти. Пусто. В том числе пусто и в архиве примеров. Искал по таким словам, как:
SqlClient
SqlConnection
Может не так искал? Единственное, что нашел - это ссылку на рабочую статистику сервера Репки2:
http://r2.repka.su/ и в общем-то и все. А очень бы хотелось глянуть несколько примеров того, как это все делается.
Вопрос подключения к базам данных это уже вопрос для специализированных форумов, и к данной теме отношение не имеет. Юзаем поисковики: mysql c# example
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
В том числе пусто и в архиве примеров.
Миссия DGW2 islands w.stat by stillborn
На Репке стат из нее.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
Вопрос подключения к базам данных это уже вопрос для специализированных форумов, и к данной теме отношение не имеет. Юзаем поисковики:
mysql c# example
Нет, меня интересуют как раз игровые скрипты. Как и в какой момент времени, заносить данные в базу. И где их, собственно, брать. А как подключиться к базе, я уже нашел. Даже нашел подключение, к базе Microsoft Access. Как к обычной, так и к защищенной.
Нужно описание:
"OnActorDamaged"
подробное описание параметра "List<DamagerScore>" в "OnActorDead"
"OnAircraftCrashLanded"
"OnAircraftDamaged"
"OnAircraftKilled"
ну, и так далее. В общем, все то, что можно было бы заносить в статистику, как данные по тому или иному пилоту.
Цитата:
Сообщение от
-atas-
Миссия DGW2 islands w.stat by stillborn
На Репке стат из нее.
Ага. Спасибо! Полез смотреть...
-
Re: Полный редактор и скрипты.
Вопрос...
В скрипте пишу так:
Код:
using System;
using maddox.game;
using maddox.game.world;
using System.Collections.Generic;
Все пашет.
Но когда пишут так:
Код:
using System;
using System.Data;
using maddox.game;
using maddox.game.world;
using System.Collections.Generic;
То в консоли сервера выдает ошибку на эту "using System.Data;".
Ошибка такая:
Код:
=================================================
System.Exception: c:\Documents and Settings\СЛАВИК\Мои документы\1C SoftClub\il-2 sturmovik cliffs of dover\missions\Multi\Dogfight\Skript.cs(3,14): error CS0234: Имя типа или пространства имен 'Data' отсутствует в пространстве имен 'System' (пропущена ссылка на сборку?)
в 2fK76H4rrxvt3dZC4k8.s2sCuh4qoKKt665i9Aa.ZfiUJaJndHR(String , Boolean , Boolean )
в 2fK76H4rrxvt3dZC4k8.s2sCuh4qoKKt665i9Aa.DOFjDteibXpNRMImCyI6(Object , Boolean , Boolean )
в 2fK76H4rrxvt3dZC4k8.s2sCuh4qoKKt665i9Aa.WEmUJe0WYUR(String )
в 2fK76H4rrxvt3dZC4k8.s2sCuh4qoKKt665i9Aa.SSlUJE8On9c(String , Int32 )
=================================================
Причем в самой среде "Microsoft Visual C# 2010" все пашет на ура.
Эта using System.Data; так же как и using System.Data.OleDb; нужны в скрипте для соединения с базой данных.. Повторюсь, что в среде "Microsoft Visual C# 2010" все пашет на ура. Соединение с базой и получение данных посредством SQL запросов работает отлично. А сервак эту Data не видит в упор.
Писал уже и с большой буквы и с маленькой. :(
Хееееелп!!!
-
Вложений: 1
Re: Полный редактор и скрипты.
Все верно, и не сможешь, т.к. такие сборки игра не подключает, соответственно ты их использовать не можешь. Поэтому всю логику пишешь в отдельной сборке а к миссии ее подключаешь.
Вот выдрал из своей работы кусок для примера.
BridgeMission.cs - непосредственно скрипт миссии, который подключает сборку, с помощью рефлексии создает экземпляр класса из сборки и извлекает необходимые методы класса.
RepkaBridge.cs - Размещается в отдельное сборке, собственно упомянутый выше класс. Как видно, убираем необходимость переопределения методов миссии, мы переводим всю кухню на событийную модель, плюс можем теперь подключать в своей сборке любые фичи.
В моем случае одним из подписчиков на эти события и есть стата.
Думаю этот пример пригодится всем кто занимается скриптами.
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
...который подключает сборку, с помощью рефлексии создает экземпляр класса из сборки и извлекает необходимые методы класса.
Ужас!!!
Для не посвященного - это тоже самое, что слова матом. Абракадабра. Ничего не понял! :( Ну, разве что так... Создаем класс. Создаем экземпляр класса. Юзаем методы этого класса. Но это все просто общие слова, которые ничего мне не поясняют.
А нет примерчика с двумя файлами? Где один скрипт, подключает другой. Ну, или, как там иначе делается?.. Мне бы глянуть разок, до меня бы дошло, (возможно).
Задача у меня такая:
Имеем некое событие в миссии. Пусть это будет то же самое широко распространенное "OnActorDead". По этому событию получаем кучу данных. Кого убили, кто убил, и так далее. Записываем эти данные в базу данных. Не в текстовый файл, как в примере упомянутым -atas- "DGW2 islands w.stat by stillborn" (который я сегодня посмотрел), а именно в полноценную базу данных. В моем случае, хотелось бы заюзать базу Microsoft Access. Для меня это был бы самый удобный вариант.
Цитата:
Сообщение от
Small_Bee
...Поэтому всю логику пишешь в отдельной сборке а к миссии ее подключаешь...
Как это сделать практически???
Предоставленный тобою пример sample.zip я уже где-то видел раньше. Он ничего поясняет. Срабатывает триггер, загружается подмиссия. И все, собственно... А на твои примерочные файлы BridgeMission.cs и RepkaBridge.cs никаких ссылок нет.
Снова кричу: - Хээээлп!!!
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Как это сделать практически???
Предоставленный тобою пример sample.zip я уже где-то видел раньше. Он ничего поясняет. Срабатывает триггер, загружается подмиссия. И все, собственно... А на твои примерочные файлы BridgeMission.cs и RepkaBridge.cs никаких ссылок нет.
Снова кричу: - Хээээлп!!!
Пример ты не мог видеть где-то раньше. Там нет никаких подмиссий и триггеров.
Этот пример поясняет, как практически подключить свою сборку к скрипту миссии и транслировать события миссии в свою сборку, а что ты будешь делать в этой сборке - твое дело, хоть к базам подключаться, хоть на бирже играть. Там нет никакой конкретной реализации, ТАМ УЖЕ ВСЕ ГОТОВО для того, что бы эту реализацию создать. А ее никто кроме тебя самого делать не будет.
Прежде чем требовать пояснений, очень не помешает хоть немного подтянуть матчасть. То, что Вы ничего не поняли из примера, это не его проблема. Тем более это файлы из рабочего проекта, которые реально работают.
-
Re: Полный редактор и скрипты.
Погоди... Ты не понял. Выложенный тобою zip-архив sample.zip с примером я видел тут:
http://wiki.sukhoi.ru/index.php?titl...81%D0%B8%D0%B9
Обычные тригеры, которые срабатывают и что-то там делают. С комментариями на немецком языке. В принципе, там все понятно, но для меня, в данном случае, бесполезно.
Я говорю, про твои примеры "BridgeMission.cs" и "RepkaBridge.cs". Где их можно посмотреть? Ты ведь ссылку на них не сделал. Только имена файлов и все.
Цитата:
Сообщение от
Small_Bee
...Прежде чем требовать пояснений, очень не помешает хоть немного подтянуть матчасть...
Упаси Бог! Никто ничего не требует!
Я ПРОШУ помощи. А матчасть... Ковыряюсь, конечно, потихоньку... Не без этого. Ну, может плохо ковыряюсь. Прости, если что не так. И спасибо, что помогаешь мне, балбесу... :)
Теорию я понял. Миссия игры транслирует в мою "Сборку" какие-то события, а эта "Сборка" их обрабатывает. Вот мне бы крохотный пример того, как это реализовать практически. Скажем, в миссии что-то бабахнуло, "Сборка" это услышала и отреагировала тем, что я там в ней напишу-нагорожу. Как заставить миссию сказать моей "Сборке" что-то? И как эта "Сборка" может слушать миссию игры? Были вроде реализации на вроде того, что некая программа в реальном времени читает (парсит) лог-файл игры и тем самым реагирует на события игровой миссии. Но это же жесть!!! Нельзя так делать.
--- Добавлено ---
Блин, сори!!!!!!!!!!!!!!!!!
Тупо запутался в архивах. Перепутал ранее скачанный "Samples.zip" с твоим выложенным "sample.zip". Вот ведь как! Тупо невнимательность...
Все, пока вопросов нет. Полез смотреть. Спасибо! :)
-
Re: Полный редактор и скрипты.
Сорри и меня, я просто немного в осадок выпал, я за Фому, а мне за Ерему. )
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
Small_Bee
Сорри и меня, я просто немного в осадок выпал, я за Фому, а мне за Ерему. )
Ага. :)
Начал смотреть код. Что-то уж больно туго он мне дается.
А можно было бы, если есть время, прокомментировать построчно эту, как я понимаю, ключевую часть кода из файла BridgeMission.cs:
Код:
private void Init(string path)
{
try
{
Assembly a = Assembly.LoadFile(path);
GamePlay.gpLogServer(null, "Assembly: {0}", new object[] { a.FullName });
Type bridgeType = a.GetType("RepkaMissionsLib.core.RepkaBridge");
GamePlay.gpLogServer(null, "Bridge: {0}", new object[] { bridgeType.Name });
if (bridgeType != null)
{
bridge = Activator.CreateInstance(bridgeType, new object[] { this });
if (bridge != null)
{
method[EventType.ActorCreated] = bridgeType.GetMethod("OnBridgeActorCreated");
method[EventType.ActorDamaged] = bridgeType.GetMethod("OnBridgeActorDamaged");
method[EventType.ActorDead] = bridgeType.GetMethod("OnBridgeActorDead");
...
В первом посту этой темы, под словами "Человеческим языком:" , у тебя уж больно здорово это получалось. Плиииз!.. :)
И что-то я не уверен, где происходит обращение к "Сборке" по факту произошедшего события в миссии. Случайно не в этом методе?
Код:
private void InvokeEvent(EventType ev, params object[] args)
{
...
}
-
Re: Полный редактор и скрипты.
Тишина в теме. Гробовая. :(
...ковырялся я, ковырялся, но мне по прежнему не ясно, как же все таки подключается библиотека. Как к ней происходит обращение из миссии и передаются параметры. Если забыть про объектно ориентированное программирование, то я думал, что будет, примерно, так:
1. Имеется один файл с расширением "cs". Это есть скрипт и код миссии. В ней происходит событие по факту убиения какого-то объекта (например).
2. Имеется второй файл с расширением "cs" в нем написаны процедуры и функции для работы с базой данных статистики.
3. В первом файле подключаем второй файл и мы как бы юзам процедуры второго файла. (так я не Дельфи когда-то делал)
Вот так мне казалось. Я совсем неправ?
Пока Small_Bee куда-то благополучно пропал (наверное дописывает статистику), представляю вашему вниманию готовый к использованию простейший скрипт и миссию, которая крутится сейчас на моем сервере.
Небольшое описание:
Имеются зенитки для защиты ВПП красных и синих. Естественно, в ходе битвы их уничтожают нерадивые злые вирпилы, дабы они не мешались. Уничтожаются они навсегда. Чтобы восстановить эти невинно убиенные зенитки на всех своих филдах, нужно подбить шесть вражеских зениток. И наоборот. Вот такое нехитрое условие для играбельности в Битве. Так же на карте, для разнообразия, стоят танкеры и минные тральщики. Танкер автоматически респавнится через каждые пол часа (после его благополучного затопления), тральщик через час.
Отличительной особенностью скрипта является то, что нет триггеров. А имена всех зениток записываются заранее во время их появления на карте, чтобы потом их можно перебирать по именам и в цикле удалять для последующего респавна. Код скрипта насыщен моими личными комментариями. Начинающим, возможно, будет полезно, а гуру прошу отнестись к ним снисходительно. Ведь я полный чайник в этом деле! И писал их лично для себя и для того, чтобы потом, через какое-то время, понять, что я там вообще нагородил.
Взять это хозяйство можно тут:
http://www.box.com/s/h734mjr2f0fnodbhvzey
-
Re: Полный редактор и скрипты.
Цитата:
Сообщение от
SlavikSG
Пока Small_Bee куда-то благополучно пропал (наверное дописывает статистику), представляю вашему вниманию готовый к использованию простейший скрипт и миссию, которая крутится сейчас на моем сервере.е на карте, для разнообразия, стоят танкеры и минные тральщики. Танкер автоматически респавнится через каждые пол часа (после его благополучного затопления), тральщик через час.
Спасибо, если завтра на митинге не пришибут, на выходных постараюсь посмотреть.
-
Re: Полный редактор и скрипты.
Славик, файл с расширением cs - это просто исходник, чтоб выполнить код из него он должен быть откомпилирован компилятором языка C#, а результат помещен в исполняемый файл (exe) или файл динамической библиотеки (dll), которые в контексте платформы .NET называются сборками. Твой файлик со скриптом миссии при ее загрузке тоже будет откомпилирован в сборку, и помещен в папку временных файлов системы. SmallBee это подробно расписал в начале темы Как реализовывать ("включать") скрипты?.
В куске кода из твоего примера:
- Загружается сборка.
- В ней ищется класс с полным именем "RepkaMissionsLib.core.RepkaBridge".
- Динамически создается экземпляр этого типа.
- Получаются описатели методов "OnBridgeActorCreated" "OnBridgeActorCreated".
- Описатели помещаются в массив, для последующего вызова.