Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • Need help?

    Create a topic in the appropriate section
    Don't write everything in the chat!
  • Take a look at the marketplace

    There you can buy
    everything related to game servers
  • Don't want a ban?

    Please read our rules
    Don't disturb the order!
  • Sell or buy?

    Use services of the guarantor
    We will make your deal safe
  • 0
Sign in to follow this  
xOk

Как проверить, является ли объект кастомным?

Всем привет!

Создал объект NPC:

m_object = GetGame().CreateObject(m_type, m_position, false, false, true);
m_object.SetPosition(m_position);
m_object.SetOrientation(m_orientation);
m_object.SetAllowDamage(false);

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

override bool ActionCondition( PlayerBase player, ActionTarget target, ItemBase item ) {
  Object obj = target.GetObject();
  if (obj && obj.IsAlive() && ???) {
  	return true;
  }

  return false;
}

Вопрос 1: как проверить, является ли объект-цель (в target) объектом-NPC?

Вопрос 2: я правильно понимаю, что ActionCondition вызывается только на клиенте, а на сервере - нет?

 

P.S.: Я пробовал модифицировать класс Object, добавив в него кастомное свойство m_xok_isNPC, и выставлять его в true при создании объекта-NPC, но при запуске сервера выдалась ошибка, что класс Object не может быть модифицрован.

 

Share this post


Link to post
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Кажется, нашёл решение.

Чтобы добавить кастомное свойство объекту нужно:

  1. Определить, к какому классу, наследующемуся от Object, больше относится Ваш объект. В моём случае - это класс PlayerBase.
  2. Модифицировать этот класс (PlayerBase), добавив к нему нужное кастомное свойство. В моём случае - это булевый флаг m_xok_isNPC.
  3. Зарегистрировать Ваше кастомное свойство для синхронизации между клиентом и сервером.

В итоге, получается примерно такой код:

modded class PlayerBase {
    bool m_xok_isNPC = false; // кастомное свойство

    override void Init() {
      super.Init();

      RegisterNetSyncVariableBool("m_xok_isNPC"); // регистрация кастомного свойства для синхронизации между клиентом и сервером
    }

    override void SetActions(out TInputActionMap InputActionMap) { // Добавляем экшен для тестирования
      super.SetActions(InputActionMap);

      AddAction(ActionXokExample, InputActionMap);
    }
}

Теперь, при создании объекта класса PlayerBase (и других классов, которые от него наследуются) у этого объекта будет свойство m_xok_isNPC, которое будет синхронизироваться между клиентом и сервером.

 

Для теста:

  1.  Создадим объект-NPC и объект, не являющийся NPC:
    modded class MissionServer {
      override void OnInit() {
        super.OnInit();
    
        // Объект, являющийся NPC
        vector pos1 = "8354.06 293.143 5995.87";
        Object obj = GetGame().CreateObject("SurvivorM_Niki", pos1, false, false, true);
        obj.SetPosition(pos1);
    
        PlayerBase man = PlayerBase.Cast(obj); // Кастим объект класса Object к объекту того класса, в который мы добавили кастомное свойство (PlayerBase).
        man.m_xok_isNPC = true; // Проставляем значение нашему кастомному свойству.
    
        // Объект, не являющийся NPC.
        vector pos2 = "8355.06 293.143 5995.87";
        Object obj = GetGame().CreateObject("HatchbackHood", pos2, false, false, true);
        obj.SetPosition(pos2);
      }
    }

     

  2. Создадим вспомогательный класс с функцией для проверки объекта на то, является он NPC или нет:
     

    class Xok_Utils {
      static bool IsNPC(Object obj) {
        PlayerBase pb = PlayerBase.Cast(obj);
    
        return pb && pb.m_xok_isNPC;
      }
    }
  3. Создадим кастомный экшен, который будет доступен только при взаимодействии с объектами-NPC:
    class ActionXokExample: ActionInteractBase {
      void ActionXokExample() {
        m_CommandUID = DayZPlayerConstants.CMD_ACTIONMOD_INTERACTONCE;
        m_StanceMask = DayZPlayerConstants.STANCEMASK_ERECT | DayZPlayerConstants.STANCEMASK_CROUCH;
        m_HUDCursorIcon = CursorIcons.CloseHood;
        m_Text = "Пример";
      }
    
      override void CreateConditionComponents() {
        m_ConditionTarget = new CCTMan(UAMaxDistances.DEFAULT);
        m_ConditionItem = new CCINone;
      }
    
      override bool ActionCondition( PlayerBase player, ActionTarget target, ItemBase item ) {
        if (GetGame().IsServer())
          return true;
    
        Object obj = target.GetObject();
        if (obj && obj.IsAlive() && Xok_Utils.IsNPC(obj)) {
          return true;
        }
    
        return false;
      }
    }
  4. Зарегистрируем экшен:
    modded class ActionConstructor {
      override void RegisterActions(TTypenameArray actions) {
        super.RegisterActions(actions);
    
        actions.Insert(ActionXokExample);
      }
    }

Теперь зайдем на сервер и проверим результат.

При взаимодействии с объектом-NPC отображается наш кастомный экшен:

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

А при взаимодействии с объектом, не являющимся NPC - нет:

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

 

 

P.S.: что касается моего 2-го вопроса, то ответ - нет. ActionCondition вызывается и на клиенте, и на сервере.

Edited by xOk (see edit history)

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site, you automaticly agree to our Guidelines and Privacy Policy.
We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.