Important Вопросы по fonline mapper

Тема в разделе "Техподдержка", создана пользователем Mighty, 24 окт 2012.

  1. Ametist

    Ametist

    Регистрация:
    22 мар 2014
    Точно все делаешь как надо?), я то чуток не так. (Я этим просто не занимался еще)
    [​IMG]
    [​IMG]
  2. Medvedev

    Medvedev

    Регистрация:
    17 сен 2014
    Именно так и делаю, но у меня в маппере пустое место вместо него. Какая версия маппера?

    Да, догадка верна - что-то не так с маппером 459 ревизии. В логе маппера пишет:

    Код:
    Reload scripts...
    Script message: mapper_main : Info : Compiling void start() : 2722, 1.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_SKIN' is not declared : 2735, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_RHANDLE' is not declared : 2736, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_LHANDLE' is not declared : 2737, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_BODY' is not declared : 2738, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_FEET' is not declared : 2739, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_HANDS' is not declared : 2740, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_HEAD' is not declared : 2741, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_HAIR' is not declared : 2742, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_EYE' is not declared : 2743, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_MUSTACHE' is not declared : 2744, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_PONYTAIL' is not declared : 2745, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_BEARD' is not declared : 2746, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_SHOULDER' is not declared : 2747, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_ARMLET' is not declared : 2748, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_BACK' is not declared : 2749, 24.
    Script message: mapper_main : Error : 'ANIM3D_LAYER_BACKPACK' is not declared : 2750, 24.
    Script::LoadScript - Unable to Build module<mapper_main>, result<-1>.
    Load module fail, name<mapper_main>.
    Reload scripts fail.
    Bind reserved functions...
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<start>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<finish>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<loop>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<console_message>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<render_iface>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<render_map>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<mouse_down>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<mouse_up>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<mouse_move>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<key_down>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<key_up>.
    Script::Bind - Module<mapper_main> not found.
    Bind reserved function fail, name<input_lost>.
    Bind reserved function fail, name<map_load>.
    Bind reserved function fail, name<map_save>.
    Bind reserved functions fail.

    Вылечил своими силами добавлением строки в mapper_main.fos:

    #include "_animation.fos"

    Теперь вот еще какая проблема: В маппере для 3d неписей появились настраиваемые параметры слоев - руки, голова, тело и пр. Но они не сохраняются - после сохранения/загрузки карты нпц стоит голый.

    В логе такая ошибка:
    Код:
    Bind reserved functions...
    Bind reserved function fail, name<map_load>.
    Bind reserved function fail, name<map_save>.
    Bind reserved functions fail.

    Ametist, проверь пожалуйста у себя и скажи какая ревизия. Если у тебя все норм - перееду на твою.
    Последнее редактирование: 15 окт 2014
  3. gevar

    gevar

    Регистрация:
    20 мар 2013
    Ребята, извиняюсь за нуб вопрос.
    как запустить маппер на 64 бит семерке? Безымянный.jpg
  4. gevar

    gevar

    Регистрация:
    20 мар 2013
    попробую поставить 476
  5. gevar

    gevar

    Регистрация:
    20 мар 2013
    не помогло(
    подскажите какую версию юзают 64-битные?
    или вот еще какой вопрос, есть ли околосерверные ревиема? хочется сделать карту, какая ревизия оптимальна, или же разницы нет?
  6. Ametist

    Ametist

    Регистрация:
    22 мар 2014
    у меня рабочия 412 версия
  7. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    Маппер последней ревизии запускается у кого? Проблемы с видимостью переменных и дефайнов:

  8. Skycast

    Skycast

    Регистрация:
    5 ноя 2011
    Да, маппер работает последний.
  9. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    Угу, завелся.
  10. Cth

    Cth

    Регистрация:
    13 авг 2017
    Добрый день, ребят.

    Нуждаюсь в помощи в связке маппера и скриптов, буквально чуток. А то самому догадываться реально много времени утекает вникуда.

    Такая ситуация. Сделал робота нпц. Умертвил его третим статусом. прописал ему диалог. Но фонлайн не дает разговаривать с мертвыми. Это печально, но я вышел из ситуации вот таким вот скриптом:

    Код:
    void _Disassemble(Critter& cr, bool firstTime)
    {
    	cr.StatBase[ST_REPLICATION_TIME] = REPLICATION_NEVER;
    //Log("_Disassemble");
    	cr.SetEvent(CRITTER_EVENT_USE_SKILL_ON_ME, "_RobotDialog");
     
    }
     
    bool _RobotDialog(Critter& me, Critter& whoUse, int skill)
    {
    	if(whoUse.IsPlayer()
    /*&& (skill == SKILL_LOOT_CRITTER || skill == SK_STEAL || skill == SK_FIRST_AID || skill == SK_DOCTOR || skill == || skill ==)*/
    )
    	{
    		RunDialog(whoUse, me.Param[ST_DIALOG_ID], me.HexX, me.HexY, true);
    		return true;
    	}
    	 return false;
    }
    Теперь диалог запускается на отличненько. Я сделал сложный диалог с кучей проверок и с диалога запускаю еще два скрипта, чтобы давать пользователю ресурсов по формулам в зависимости от их скиллов.

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

    Теперь самая важная деталь. Тестил я это на локальных и глобальных переменных пользователя. Ясное дело, что для такой мелочи ни локальные ни глобальные переменные не нужны. Вообще-то, у меня тут огромная пещера и я хотел бы в ней разместить несколько копий этого робота. Проблема в том, что чтобы эти копии работали отдельно друг от друга, моя защитная переменная должна храниться на стороне нпс, а не пользователя. Ну или быть уникумом, что описывает отношение 1<->1.

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

    1. Сделать неубиваемого живого робота в третьем/втором состоянии. Но не перекачанным прототипом, а должен быть где-то какой-то флаг, что этот непись как бы и мертв, но переменные свои хранит.
    2. Использовать сценери мертвого робота. Это вообще было бы круто, но я не уверен может ли сценери работать с переменными диалогера. Может ли сценери хранить переменные. Думаю нет. Но я не пробовал пока. Просто сама функция диалога требует два аттрибута: игрок и нпс. Ну и туда передается игрок и нпс. А если это сценери, то мне придется где-то прятать нпс и типа проводить разговор с ним. А это совершенно убого выглядит. Фт1/2 делали так. Я такие хаки юзать не хочу.
    3. Полностью весь диалог и проверки сделать в скрипте. Но это геморройный вариант. Я еще не знаком с фосом достаточно хорошо, мне каждый кусок функционала приходится угадывать поиском по всем остальным скриптам сервера.
    4. Играться с особыми сценери типа компов (мне кажется они умеют хранить переменки), но оверрайднуть им скин в дохлого робота
    Прям варианты есть. Мне хотелось бы узнать как реализовывать каждый и какой будет самым человечным вариантом по отношении к движуле.

    Спасибо!

    Кстати, раз уж я сюда добрался, вопросов по мапперу реально почти нету, там я практически со всем уже разобрался. А вот вопросы по фосу возникают. Есть такая же темка для простецких вопросов по фосу?

    PS

    Моя ревка - 392. Это фонлайн релоадед.
    Последнее редактирование: 16 авг 2017
  11. Tawaruuk

    Tawaruuk

    Регистрация:
    4 авг 2016
    Вроде не было. Создай по аналогии с этой.
    Cth нравится это.
  12. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    Гамевары не должны чиститься после смерти нпс, только по удалению.

    1) - Вешай мод неуязвимый же MODE_INVULNERABLE.

    PS

    Возможно разумно использовать ST_VAR у криттера, и не париться?
    Cth нравится это.
  13. Cth

    Cth

    Регистрация:
    13 авг 2017
    MODE_INVULNERABLE - это в прото только вешается, или можно неписю в исходнике карты повесить?

    Что значит ST_VAR у криттера?

    По диалогам тоже создать?
  14. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    Можно в маппере, если открыть параметр для редактирования в маппере, но это излишне. Лучше повесить скрипт инициализации на криттера, и менять там.

    ST_VAR это ST_VAR0 ST_VAR1 ... ST_VAR9 переменные для специфичных использований вообщем.
    Cth нравится это.
  15. Cth

    Cth

    Регистрация:
    13 авг 2017
    но я эти специфичные переменные не смогу использовать в диалогере? Диалогер же жует только то, что в _vars.fos. А эти выглядят как статы. Я так понимаю, что они как статы и работают. Статы менять можно только скриптами, получается что мне в диалогере вместо простых проверок и задания переменных нужно будет каждый раз скрипт звать и им уже проверять и задавать эти статы-переменные. Это адекватно вообще? Я могу, но адекватно ли это...

    Что-то мне подсказывает, что MODE_INVULNERABLE чуток адекватней решением будет здесь.

    Кстати, что по поводу диалогов с scenery? Это можно?
  16. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    2017-08-16.png

    С сценери нельзя, разговоров с сценери как таковых не существует ( могу ошибаться, лучше перепроверить конечно ), только разговор с гексом или криттером. В теории можно конечно реализовать это все, сохраняя данные перед RunDialog , и придумать алгоритм создания уникального индекса для сценери для того чтобы вешать геймвары на него, но это все не особо адекватно.
    Cth нравится это.
  17. Cth

    Cth

    Регистрация:
    13 авг 2017
    Разговор с гексом? Это то, как работают терминалы? Они ж не нпс. Гексы умеют хранить нпц-переменные?

    Если сценери не умеет болтать, тогда что это?
    [​IMG]

    ухтыыы так st_var - это не переменная, а параметр! круть, блин, мог бы и сам догадаться. Все, у меня уже есть несколько вариантов как делать что я хочу, спасибо :)

    Попробовал st_var0. Не работает он. В логику его ввел, но он ни на что не влияет.

    [​IMG]

    Как только бот живой, в смысле статус бота 1 - все сразу работает как надо. Если статус 2, или 3 - переменная не сохраняется. Короче, я делаю робота живым, прописываю ему 86ю анимацию и делаю его бессмертным. Все прекрасно, только он крутится когда с ним говоришь и атакует, если его атаковать.

    По-моему, где-то был вариант запретить нпс любые телодвижения. Да?
    Последнее редактирование: 17 авг 2017
  18. Medvedev

    Medvedev

    Регистрация:
    17 сен 2014
    Cth, у сценери нет параметров:

    Открытые члены
    bool CallSceneryFunction (Critter &cr, int skill, Item @item)
     Вызывает функцию сценери ассоциированную с указанным Scenery объектом. Подробнее...
     

    Открытые атрибуты
    const uint16 HexX
     Координата месторасположения по оси X. Подробнее...
     
    const uint16 HexY
     Координата месторасположения по оси Y. Подробнее...
     
    const uint16 ProtoId
     ID прототипа. Подробнее...
    Открытие диалога достигается путем срабатывания скрипта, который на нем висит.
    Cth нравится это.
  19. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    Посмотрел как ты запускаешь диалог с мертвым, понятно почему его параметры не учитываются. У тебя опять же разговор с гексом, поэтому нпц в разговоре нету.
    Cth нравится это.
  20. Cth

    Cth

    Регистрация:
    13 авг 2017
    Ой. Спасибо, ща перепишу :) хехе :) забавно получается. А как тогда этот непись умудряется хранить переменную когда он жив? Жесть вообще. Я же с хексом говорю... Вот это даааа... Волшебный движок. Щас перепишу и попробую потестить разговор с мертвым неписем, спасибо большое :) Я не заметил, что не тот конструктор юзаю. Блин.

    StaleCracker, я переписал функцию, теперь диалог с неписем запускается. Вот что я получаю в игре:
    [​IMG]

    Короче, не важно каким методом я говорю: через первый метод, или второй, я никак не могу говорить с мертвыми неписями. Если бы где-то был оверрайд этого... Я думаю где-то он есть, но жаль что не в методе.

    Ребят, есть идеи как сделать диалог с мертвым роботом так, чтобы он свои переменные хранил? Должен же быть путь проще... Что-то вроди флага в прото робота, что может разговаривать после смерти. Хыхы :)

    Medvedev, а вот айтем в том методе - это что? типа сценери айди? Не прото же? Где его брать? Сорри за глупый вопрос.

    ============

    На самом деле, у меня уже есть два варианта как это сделать:

    1. Сделать живого робота, дать ему анимацию мертвого, сделать его бессмертным и как-то (я пока не знаю как) сделать так, чтобы он не менял направления, не двигался и не отвечал на атаки.

    2. Сделать мертвого робота и диалог с хексом, но хранить переменные на стороне игрока и делать их локальными. Возможно локальными к карте. Но тогда мне прийдется создавать новую копию диалога с новой переменной при копировании этого робота, что тоже выглядит уродливо.

    Сами понимете, оба варианта корявые, я хочу элегантное решение.
    Последнее редактирование: 17 авг 2017
  21. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    "Ой. Спасибо, ща перепишу :) хехе :) забавно получается. А как тогда этот непись умудряется хранить переменную когда он жив? Жесть вообще. Я же с хексом говорю... Вот это даааа... Волшебный движок. Щас перепишу и попробую потестить разговор с мертвым неписем, спасибо большое :) Я не заметил, что не тот конструктор юзаю. Блин."

    Когда он живой, ты говоришь через иконку разговора, он не обрабатывается ивентом твоим, и запускает разговор напрямую. Потому в этом случае он участвует в разговоре, и доступ к его переменным есть.

    Вешай на этих нпц роли, ищи во время диалога через скрипты, и возвращай значения опять же через скрипт. Все условия и результаты делай в фосах, а не диалогах. Можно и игроку записывать ид этого нпц куда нибудь, и обращаться через этот ид из диалога ( точнее с скрипта вызванного диалогом ).

    "Medvedev, а вот айтем в том методе - это что? типа сценери айди? Не прото же? Где его брать? Сорри за глупый вопрос. "
    Этот метод вызывает функцию повешанную на сценери, таким образом итем ты можешь передавать какой тебе захочется. В функции обработчике когда она запускается напрямую с движка итем может быть только тем, который юзается на этот сценери.
    Cth нравится это.
  22. Cth

    Cth

    Регистрация:
    13 авг 2017
    Когда он мертвый, я говорю через свой скрипт, но в скрипте этот непись тоже есть и в диалоге он участвует. У нас только два конструктора диалога. При прямом разговоре юзается тот же конструктор, который я щас зову. И он дает отбой если нпц мертв.

    не-не-не-не, я не хочу переписывать функционал диалогера в фосе. Я знаю, что я это могу делать, но это так неловко, что я этот вариант даже не рассматриваю. Я скорей буду делать ненужные копии диалогов, чем переписывать диалог в фосе.

    Должно быть более простое решение для диалогов с мертвыми нпц или сценери. Я не понимаю, а как компы умудряются хранить нпц-переменные? Или у них там диалоги тоже брутально в фосе сделаны?

    Ага, по поводу итема понял, спасибо.

    Ребят, у меня еще были идеи, и я их задавал англоязычным девелоперам, но они не знают. Раз я уже тут спрашиваю, то спрошу - можно ли удалять сценери и блокеры движения из скриптов? Я хочу типа как бы путь открывать по ходу прохождения квеста. Можно так?
    Последнее редактирование: 17 авг 2017
  23. Medvedev

    Medvedev

    Регистрация:
    17 сен 2014
    Cth, он для использования в тех случаях, когда на сценери применяется предмет.
    Cth нравится это.
  24. Cth

    Cth

    Регистрация:
    13 авг 2017
    да, да, я понял, спасибо. Очень интересно, я буду юзать эти штуки обязательно.
  25. Cth

    Cth

    Регистрация:
    13 авг 2017
    А не найдется примера такого диалога? Там, чувствую, много мне на угад придется тыкаться пока не закончу, было бы куда легче с примером. И я так понимаю, что переменные, обьявленные в скрипте инициализации, можно передавать ссылкой в функции и потом менять их там глобально. И эти переменные удалятся только с деспавном инициализировавшегося обьекта? Когда игрок покинет карту.
  26. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    Самое простое для сервера это запоминание ид перед стартом диалога.

    Сделай гамевар допустим TalkNpcId, тут будет храниться ид криттера с которым ведется диалог.
    В твоем bool _RobotDialog(Critter& me, Critter& whoUse, int skill) перед вызовом диалога ( перед RunDialog ) сохраняй айди робота туда.
    Типо:
    ::GameVar@ varNpcId = ::GetLocalVar( LVAR_TalkNpcId, whoUse.Id );
    if( @varNpcId !is null )
    {
    varNpcId = me.Id;
    ::RunDialog( ... );
    }

    Дальше все действия с этой переменной делай в скрипте.

    Типо:

    bool d_IsRobotHard( ::Critter& master, ::Critter@ slave)
    {
    if( @slave is null )
    {
    ::GameVar@ varNpcId = ::GetLocalVar( LVAR_TalkNpcId, master.Id );
    if( @varNpcId is null )
    return false;

    ::Critter@ realNpc = ::GetCritter(varNpcId.GetValue());
    return ( ( @realNpc !is null ) && ( realNpc.Stat[ST_VAR0] == 0 && ( master.Skill[SK_SCIENCE] >=46 || master.Skill[SK_REPAIR]>=46 ) ) );
    }
    return false;
    }

    2017-08-18.png

    Это твое условие на 3ий ответ 2ой ветки.

    По хорошему нужно еще проверки разные делать на нахождении рядом с ботом и подобным, и в результате перепроверить снова. Чтобы обезопасить диалог.
    Cth нравится это.
  27. Cth

    Cth

    Регистрация:
    13 авг 2017
    А ну скажи, правильно ли я понял идею.

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

    Только почему GetLocalVar( LVAR_TalkNpcId, whoUse.Id ); вернет что-то вразумительное? У игрока нету такой локальной переменной. Ее создать наверное надо бы, или что?

    И мы разве не можем создавать локальные переменные типа обьектов... Без явного обьявления классов, чтобы хранить в таких обьектах айди нпс и значение его предохранителя.

    ЗЫ

    Все еще не верится, что нигде нету возможности давать мертвым неписям хранить свои переменные. Прям ну не верится.
    Последнее редактирование: 19 авг 2017
  28. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    Мертвые неписи хранят переменные, просто в диалоге ты мертвого непися не обработаешь.
    Удаляться буду вместе с игроком, потому что хранятся они на игроке.
    Не хочешь использовать ГамеВар, можешь использовать любое свободное поле криттера-игрока, выдели Парамс или зарегай через прагму новое поле, так будет даже лучше, сам не люблю гамевары.
    Можно и через NpcRole, но это большая нагрузка, ибо тебе придется через цикл находить близжайшего непися к игроку, в том случае если на карте ты хочешь делать нескольких таких роботов.
    С другой стороны ты можешь просто искать непися по координатом игрока сдвинуттым на 1 в сторону player.Dir, это должно работать.

    Типо:

    bool d_IsRobotHare( ::Critter& player, ::Critter@ )
    {
    ::Map@ map = player.GetMap();
    if( @map !is null )
    {
    uint16 hexX = player.HexX, hexY = player.HexY;
    map.MoveHexByDir( hexX, hexY, player.Dir, 1);
    ::Critter@ realNpc = map.GetCritter( hexX, hexY );

    ... Proccess ...

    }
    }
    Последнее редактирование: 19 авг 2017
  29. Cth

    Cth

    Регистрация:
    13 авг 2017
    окей, но мне не нравится идея циклического поиска тоже не самый элегантный выход, но круто что ты сказал, что проблема в диалоге, а не в неписе, так как я могу сделать диалоговые проверки и сам, как ты и сказал, через параметры непися.

    Смотри, диалогер все еще запускает фосы при мертвом неписе. Каждая таким образом запущенная функция получает два стройных обьекта - игрока и непися. Раз обьект непися у меня есть, значит есть доступ ко всем его переменным и айди, хотя айди нам уже нафиг не нужен, я же могу переписать метод немножко и принимать непися by reference. И делать с ним что хочу как хочу.

    То есть, я просто перепишу все манипуляции с переменными в фосе и буду звать этот фос с диалогера. Это можно сделать одним простым методом. Никакие циклы поиска не нужны, при этом.

    Все, пойдет. Получается, я что-то вроди оверрайдну родную функцию работы с переменными непися, но не включу в нее проверку живости непися.

    На самом деле, есть еще и другой путь. Делать таки проверочную переменную на стороне пользователя, но в конце работы с неписем удалять непися DeleteNpc(npc); и чистить переменную. Но у меня эта функция удаления как-то некорректно срабатывала. Вообще ничего не делала неписю. Хз как она работает. Написано, что удаляет непися в конце игрового цикла. А что такое игровой цикл. Это то, что происходит по четыре раза в секунду, или это время до следующего ребута сервера...

    Таак... а как получить доступ к переменным непися... Это они в прото где-то у меня? Ага, вот я возьму первую попавшуюся: StatBase[ST_EXPERIENCE] Это, я так понимаю, экспа которая с этого моба падает. Хз только она будет переписываться у конкретного непися, или у целого класса.
    Последнее редактирование: 19 авг 2017
  30. StaleCracker

    StaleCracker

    Регистрация:
    19 фев 2011
    Игровой цикл это то что происходит по 4 раза в секунду, да ( хотя 4 это очень мало... ).
    Непись может не удалится, если ему за игровой цикл сменить позицию ( вроде, с итемами так, лучше перепроверить информацию ). После DeleteNpc у него будет изменен флаг валидности, IsNotValide на true. И этот флаг нужно проверять вместе с обычной проверкой валидности тогда, когда нету необходимости в обратном, чего никто никогда не делал.

Поделиться этой страницей