Перейти к контенту

Справочник по функциям и классам


Рекомендуемые сообщения

...Как тут поможет разделение и творчество?

Прямо пропорционально.

Теоретически - пробуй разделять диалог по две фразы(точнее в тех местах, где необходимо "слушать" собеседника). Первая ГГ, вторая НПС. Диалог закрывается, но перед ним вызывается action, в котором после ожидания проигрывания звука вызывается start_stop_menu (я где-то делал - лень искать, спроси у Garry_Galler-а, он этим серьёзнее занимался) и следующие две фразы...В последней фразе start_stop_menu не вызывается.

Изменено пользователем Gun12
Ссылка на комментарий

Народ, у вас интересное обсуждение, но мне же придётся его потереть как оффтоп. Жалко ведь! Так что идите вы... в ковырялку.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Выкладываю небольшой разбор содержимого полей таблицы db.storage, которое относится в NPC.

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

ЗЫ: Оформлено все в виде функции, которая содержит таблицу: строковой идентификатор=значения поля и возвращает значения того или иного поля db.storage по его идентификатору в таблице и айди NPC ( вызов примерно такой - GetData(level_object_by_sid(sid), "target_state") ). Там где используется много операторов and - это способ защиты от вылета при обращении к несуществующему полю таблицы. Распечатку таблицы я делал сразу по всем полям, а так как у разных NPC содержание полей было разным, то такие проверки избавляли меня от вылетов.

ЗЗЫ: Данную функцию можно использовать только в тестовых целях, а не для реального применения.

  ---------------------------------------------------------------------------------------------
function GetData(npc, type)
local tMgr ={

---------------------------------------------------------------------------------------------
  --// поля стейт менеджера
    ---------------------------------------------------------------------------------------------
    state_mgr          = db.storage[npc:id()].state_mgr,                      --// юзердата класса state_manager
    target_state       = db.storage[npc:id()].state_mgr.target_state,         --// string название состояние из state_lib
    current_direction  = db.storage[npc:id()].state_mgr.current_direction,    --// vector или nil - направление взгляда? 
    target_position    = db.storage[npc:id()].state_mgr.target_position,      --// vector позиция (своя или того на кого смотрит?)  или nil
    current_object     = db.storage[npc:id()].state_mgr.current_object,       --// number  (-1  или nil)
    combat             = db.storage[npc:id()].state_mgr.combat,               --// boolean - находится ли в состоянии боя
    alife              = db.storage[npc:id()].state_mgr.alife,                --// boolean - под алайфом или нет?
    emerg              = db.storage[npc:id()].state_mgr.emerg,                --// table, в которой должны быть поля: animation и animation_nout, однако почему то их нет 
    synsound           = db.storage[npc:id()].state_mgr.synsound,             --//  ??
    yaw_delta          = db.storage[npc:id()].state_mgr.yaw_delta,            --// number  угол точности - 5 (градусов вроде)
    subanim            = db.storage[npc:id()].state_mgr.subanim,              --//  number  - 0 глубина рекурсивности анимации 
    need_reweapon      = db.storage[npc:id()].state_mgr.need_reweapon,        --// boolean 
    
    look_object        = db.storage[npc:id()].state_mgr.look_object,          --// number  - айди  объекта  на которого NPC предписано  смотреть 
    look_position      = db.storage[npc:id()].state_mgr.look_position,        --// vector  - позиция куда предписано смотреть
    ---------------------------------------------------------------------------------------------
    --// прочие поля
    ---------------------------------------------------------------------------------------------
    move_mgr           = db.storage[npc:id()].move_mgr,                       --// юзердата класса move_mgr
    state              = db.storage[npc:id()].state,                          --// должно быть юзердатой класса  -- но у меня возвращалось nil 
    ---------------------------------------------------------------------------------------------
    hit                = db.storage[npc:id()].hit,                            --// table   (но у меня таблица была nil - даже после нанесения хита NPC, в ней должно быть поле hit.who  - айди того, кто нанес хит
    ---------------------------------------------------------------------------------------------
    enemy              = db.storage[npc:id()].enemy,                          --// юзердата текущего врага
    ---------------------------------------------------------------------------------------------
    death                   = db.storage[npc:id()].death,                          --// table
    death_section           = db.storage[npc:id()].death.section,                  --// string - имя секции логики
    death_scheme            = db.storage[npc:id()].death.scheme,                   --// string   имя схемы
    death_npc               = db.storage[npc:id()].death.npc,                      --// userdata
    death_actions           = db.storage[npc:id()].death.actions,                  --// table
    death_userdata          = db.storage[npc:id()].death.actions.userdata,         --// boolean
    
    death_info              = db.storage[npc:id()].death.info[1],                                                       --// table
    death_info_section      = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].section,       --//??
    death_info_infop_check  = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_check and db.storage[npc:id()].death.info[1].infop_check[1],   --// table
    death_info_infop_check_expected  = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_check and db.storage[npc:id()].death.info[1].infop_check[1] and db.storage[npc:id()].death.info[1].infop_check[1].expected,    --// boolean
    death_info_infop_check_func      = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_check and db.storage[npc:id()].death.info[1].infop_check[1] and db.storage[npc:id()].death.info[1].infop_check[1].func,       --//string
    death_info_infop_set    = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_set and db.storage[npc:id()].death.info[1].infop_set[1],     --// table
    death_info_infop_set_name    = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_set and db.storage[npc:id()].death.info[1].infop_set[1].name,               --// string - имя инфопоршня
    death_info_infop_required    = db.storage[npc:id()].death.info[1]  and db.storage[npc:id()].death.info[1].infop_set and db.storage[npc:id()].death.info[1].infop_set[1].required,           --//boolean
    
    death_info2             = db.storage[npc:id()].death.info[2],                                                       --// table
    death_info_section2     = db.storage[npc:id()].death.info[2]  and db.storage[npc:id()].death.info[2].section,       --//??
    death_info_infop_check2 = db.storage[npc:id()].death.info[2]  and db.storage[npc:id()].death.info[2].infop_check,   --// table
    death_info_infop_set2   = db.storage[npc:id()].death.info[2]  and db.storage[npc:id()].death.info[2].infop_set,     --// table
    ---------------------------------------------------------------------------------------------
    danger                 = db.storage[npc:id()].danger,                         --// table
    danger_ini             = db.storage[npc:id()].danger.ini,                     --// userdata
    danger_npc             = db.storage[npc:id()].danger.npc,                     --// userdata
    danger_section         = db.storage[npc:id()].danger.section,                 --// string
    danger_scheme          = db.storage[npc:id()].danger.scheme,                  --// string
    ignore_types           = db.storage[npc:id()].danger.ignore_types,            --// table - содержит строки игнорируемых типов объектов
    ---------------------------------------------------------------------------------------------
    abuse                  = db.storage[npc:id()].abuse,                                           --// table
    abuse_npc              = db.storage[npc:id()].abuse.npc,                                       --// userdata
    abuse_manager          = db.storage[npc:id()].abuse.abuse_manager,                             --// userdata класса CAbuseManager
    abuse_ini              = db.storage[npc:id()].abuse.ini,                                       --// userdata
    abuse_section          = db.storage[npc:id()].abuse.section,                                   --// string имя секции логики
    abuse_scheme           = db.storage[npc:id()].abuse.scheme,                                    --// string  имя схемы
    ---------------------------------------------------------------------------------------------
    wounded                      = db.storage[npc:id()].wounded,                                    --// table
    wounded_set                  = db.storage[npc:id()].wounded.wounded_set,                        --// boolean - флажок что скрипт вызывался 
    use_medkit                   = db.storage[npc:id()].wounded.use_medkit,                         --// boolean
    help_dialog                  = db.storage[npc:id()].wounded.help_dialog,                        --// string  имя диалога помощи
    wounded_section              = db.storage[npc:id()].wounded.wounded_section,                    --// string
    wounded_scheme               = db.storage[npc:id()].wounded.scheme,                             --// string  
    wounded_npc                  = db.storage[npc:id()].wounded.npc,                                --// userdata
    wounded_ini                  = db.storage[npc:id()].wounded.ini,                                --// userdata
    wound_manager                = db.storage[npc:id()].wounded.wound_manager,                      --// userdata класса Cwound_manager

    
    hp_state_infop_check               = db.storage[npc:id()].wounded.hp_fight[1].state.infop_check,      --// table  
    hp_state_infop_set                 = db.storage[npc:id()].wounded.hp_fight[1].state.infop_set,        --// table 
    
    hp_cover_state_infop_check         = db.storage[npc:id()].wounded.hp_cover[1].state.infop_check,      --// table
    hp_cover_state_infop_set           = db.storage[npc:id()].wounded.hp_cover[1].state.infop_set,        --// table
    
    hp_victim_state_infop_check        = db.storage[npc:id()].wounded.hp_victim[1].state.infop_check ,    --// table  
    hp_victim_state_infop_set          = db.storage[npc:id()].wounded.hp_victim[1].state.infop_set,       --// table     
    
    hp_fight_state_infop_check         = db.storage[npc:id()].wounded.hp_fight[1].state.infop_check,      --// table
    hp_fight_state_infop_set           = db.storage[npc:id()].wounded.hp_fight[1].state.infop_set,        --// table
    
    hp_state_see                       = db.storage[npc:id()].wounded.hp_state_see[1],                          --// table
    hp_state_see                       = db.storage[npc:id()].wounded.hp_state_see[1].dist,                     --// number  --дистанция 
    hp_state_see_state                 = db.storage[npc:id()].wounded.hp_state_see[1].state[1],                 --// table
    hp_state_see_state_section         = db.storage[npc:id()].wounded.hp_state_see[1].state[1].section,         --// string
    hp_state_see_state_infop_check     = db.storage[npc:id()].wounded.hp_state_see[1].state[1].infop_check,     --// table
    hp_state_see_state_infop_set       = db.storage[npc:id()].wounded.hp_state_see[1].state[1].infop_set,       --// table
    hp_state_see_sound                 = db.storage[npc:id()].wounded.hp_state_see[1].sound[1],                 --// table
    hp_state_see_sound_section         = db.storage[npc:id()].wounded.hp_state_see[1].sound[1].section,         --// string
    hp_state_see_sound_infop_check     = db.storage[npc:id()].wounded.hp_state_see[1].sound[1].infop_check,     --// table
    hp_state_see_sound_infop_set       = db.storage[npc:id()].wounded.hp_state_see[1].sound[1].infop_set,       --// table
    
    
    psy_state_state                    = db.storage[npc:id()].wounded.psy_state[1].state[1],                 --// table
    psy_state_state_section            = db.storage[npc:id()].wounded.psy_state[1].state[1].section,         --// string имя состояния
    psy_state_state_infop_check        = db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1],                --// table
    psy_state_state_infop_check_expected    = db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1] and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1].expected,  --// boolean
    psy_state_state_infop_check_func        = db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1] and db.storage[npc:id()].wounded.psy_state[1].state[1].infop_check[1].func,      --// string
    psy_state_state_infop_set          = db.storage[npc:id()].wounded.psy_state[1].state[1].infop_set,       --// table
    psy_state_state2                   = db.storage[npc:id()].wounded.psy_state[1].state[2],                 --// table
    psy_state_state_section2           = db.storage[npc:id()].wounded.psy_state[1].state[2].section,         --// string  имя состояния
    psy_state_state_infop_check2       = db.storage[npc:id()].wounded.psy_state[1].state[2].infop_check,     --// table
    psy_state_state_infop_set2         = db.storage[npc:id()].wounded.psy_state[1].state[2].infop_set,       --// table
    psy_state_sound                    = db.storage[npc:id()].wounded.psy_state[1].sound[2],                 --// table
    psy_state_sound2                   = db.storage[npc:id()].wounded.psy_state[1].sound[2],                 --// table
    
    wounded_syndata                    = db.storage[npc:id()].wounded.syndata,                   --// table
    state_wounded                      = db.storage[npc:id()].wounded.wound_manager.state,       --// string состояние физ. ранености wounded_heavy\wounded_heavy_2\wounded_heavy_3  или пси-ранености
    ---------------------------------------------------------------------------------------------
    overrides                          = db.storage[npc:id()].overrides,                      --// table - оверрайды схем, типа combat_ignore_keep_when_attacked=false или companion_enabled=false
    ---------------------------------------------------------------------------------------------
    actor_dialogs                      = db.storage[npc:id()].actor_dialogs,                  --// table - видимо список  разрешенных диалогов
    ---------------------------------------------------------------------------------------------
    actor_disable                      = db.storage[npc:id()].actor_disable,                  --// table - это тогда список  запрещенных диалогов
    ---------------------------------------------------------------------------------------------
    meet                               = db.storage[npc:id()].meet,                           --// table
    meet_npc                           = db.storage[npc:id()].meet.npc,                       --// userdata
    meet_manager                       = db.storage[npc:id()].meet.meet_manager,              --// userdata класса Cmeet_manager
    meet_precond                       = db.storage[npc:id()].meet.precond,                   --// string
    meet_abuse                         = db.storage[npc:id()].meet.abuse,                     --// boolean
    meet_set                           = db.storage[npc:id()].meet.meet_set,                  --// boolean
    init_meet                          = db.storage[npc:id()].meet.init_meet,                 --// ?? пустая строка
    meet_section                       = db.storage[npc:id()].meet.meet_section,              --// string  имя секции логики
    meet_scheme                        = db.storage[npc:id()].meet.scheme,                    --// string
    meet_ini                           = db.storage[npc:id()].meet.ini,                       --// userdata
    
    meet_use_section                   = db.storage[npc:id()].meet.use.section,               --// boolean
    meet_use_infop_check               = db.storage[npc:id()].meet.use.infop_check,           --// table
    meet_use_infop_set                 = db.storage[npc:id()].meet.use.infop_set,             --// table
    meet_use_wpn                       = db.storage[npc:id()].meet.use_wpn[1],                --// table
    meet_victim                        = db.storage[npc:id()].meet.victim[1],                 --// table
    meet_victim_state                  = db.storage[npc:id()].meet.victim.state,              --// table
    meet_victim_dist                   = db.storage[npc:id()].meet.victim.dist,                 --// number - дистанция
    meet_victim_wpn                    = db.storage[npc:id()].meet.victim_wpn[1],             --// table
    meet_victim_wpn_state              = db.storage[npc:id()].meet.victim_wpn[1].state,       --// table
    meet_victim_wpn_state1             = db.storage[npc:id()].meet.victim_wpn[1].state and db.storage[npc:id()].meet.victim_wpn[1].state[1],       --// table
    meet_victim_wpn_state1_infop_check = db.storage[npc:id()].meet.victim_wpn[1].state and db.storage[npc:id()].meet.victim_wpn[1].state[1]  and db.storage[npc:id()].meet.victim_wpn[1].state[1].infop_check,   --// table
    meet_victim_wpn_state1_infop_set   = db.storage[npc:id()].meet.victim_wpn[1].state and db.storage[npc:id()].meet.victim_wpn[1].state[1]  and db.storage[npc:id()].meet.victim_wpn[1].state[1].infop_set,     --// table
    meet_victim_wpn_state1_section     = db.storage[npc:id()].meet.victim_wpn[1].state and db.storage[npc:id()].meet.victim_wpn[1].state[1]  and db.storage[npc:id()].meet.victim_wpn[1].state[1].section,       --// string  
    
    meet_state_state                  = db.storage[npc:id()].meet.meet_state[1].state[1],    --// table
    meet_state_state_section          = db.storage[npc:id()].meet.meet_state[1].state[1] and db.storage[npc:id()].meet.meet_state[1].state[1].section,  --// string  имя состояния
    meet_state_sound                  = db.storage[npc:id()].meet.meet_state[1].sound[1],    --// table
    meet_state_sound_section          = db.storage[npc:id()].meet.meet_state[1].sound[1] and db.storage[npc:id()].meet.meet_state[1].sound[1].section,    --// string   секция звуковой схемы
    meet_state_state_infop_check      = db.storage[npc:id()].meet.meet_state[1].state[1].infop_check and db.storage[npc:id()].meet.meet_state[1].state[1].infop_check[1],    --// table
    meet_state_state_infop_set        = db.storage[npc:id()].meet.meet_state[1].state[1].infop_set,    --// table
    meet_state_sound_infop_check      = db.storage[npc:id()].meet.meet_state[1].sound[1].infop_check and db.storage[npc:id()].meet.meet_state[1].sound[1].infop_check[1],    --// table
    meet_state_sound_infop_set        = db.storage[npc:id()].meet.meet_state[1].sound[1].infop_set,    --// table
    
    meet_zone                         = db.storage[npc:id()].meet.zone,                      --// table
    meet_state_wpn                    = db.storage[npc:id()].meet.meet_state_wpn[1],         --// table
    meet_state_wpn_state              = db.storage[npc:id()].meet.meet_state_wpn[1].state,   --// table
    meet_state_wpn_state1             = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[1],   --// table
    meet_state_wpn_state1_infop_check = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[1] and db.storage[npc:id()].meet.meet_state_wpn[1].state[1].infop_check and db.storage[npc:id()].meet.meet_state_wpn[1].state[1].infop_check[1],   --// table
    meet_state_wpn_state1_infop_set   = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[1] and db.storage[npc:id()].meet.meet_state_wpn[1].state[1].infop_set,     --// table
    meet_state_wpn_state1_section     = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[1] and db.storage[npc:id()].meet.meet_state_wpn[1].state[1].section,       --// string  - имя анимки
    meet_state_wpn_state2_infop_check = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[2] and db.storage[npc:id()].meet.meet_state_wpn[1].state[2].infop_check,   --// table
    meet_state_wpn_state2_infop_set   = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[2] and db.storage[npc:id()].meet.meet_state_wpn[1].state[2].infop_set,     --// table
    meet_state_wpn_state2_section     = db.storage[npc:id()].meet.meet_state_wpn[1].state and db.storage[npc:id()].meet.meet_state_wpn[1].state[2] and db.storage[npc:id()].meet.meet_state_wpn[1].state[2].section,       --// string  - имя анимки
    
    
    meet_state_wpn_sound             = db.storage[npc:id()].meet.meet_state_wpn[1].sound,   --// table
    meet_state_wpn_dist              = db.storage[npc:id()].meet.meet_state_wpn[1].dist,    --// number  дистанция
    meet_dialog                      = db.storage[npc:id()].meet.meet_dialog[1],            --// table
    meet_dialog_section              = db.storage[npc:id()].meet.meet_dialog[1] and db.storage[npc:id()].meet.meet_dialog[1].section,    --// string   имя диалога встречи
    meet_dialog_infop_check          = db.storage[npc:id()].meet.meet_dialog[1] and db.storage[npc:id()].meet.meet_dialog[1].infop_check,--// table
    meet_dialog_infop_check1         = db.storage[npc:id()].meet.meet_dialog[1] and db.storage[npc:id()].meet.meet_dialog[1].infop_check and db.storage[npc:id()].meet.meet_dialog[1].infop_check[1],--// table
    meet_dialog_infop_set            = db.storage[npc:id()].meet.meet_dialog[1] and db.storage[npc:id()].meet.meet_dialog[1].infop_set,   --// table
    meet_dialog2                     = db.storage[npc:id()].meet.meet_dialog[2],                                                           --// table
    meet_dialog_section2             = db.storage[npc:id()].meet.meet_dialog[2] and db.storage[npc:id()].meet.meet_dialog[2].section,    --// string имя диалога встречи
    meet_dialog_infop_check2         = db.storage[npc:id()].meet.meet_dialog[2] and db.storage[npc:id()].meet.meet_dialog[2].infop_check,--// table
    meet_dialog_infop_set2           = db.storage[npc:id()].meet.meet_dialog[2] and db.storage[npc:id()].meet.meet_dialog[2].infop_set,   --// table
    meet_syndata                     = db.storage[npc:id()].meet.syndata,                   --// table
    
    ---------------------------------------------------------------------------------------------
    section_logic           = db.storage[npc:id()].section_logic,                              --// string имя секции логики
    ---------------------------------------------------------------------------------------------
    loaded_section_logic    = db.storage[npc:id()].loaded_section_logic,                       --// string имя секции логики
    ---------------------------------------------------------------------------------------------
    active_section          = db.storage[npc:id()].active_section,                             --// string имя активной секции логики
    ---------------------------------------------------------------------------------------------
    loaded_active_section   = db.storage[npc:id()].loaded_active_section,                      --// string имя активной секции логики
    ---------------------------------------------------------------------------------------------
    active_scheme           = db.storage[npc:id()].active_scheme,                              --// string тип активной  схемы логики walker\camper\remark и т.д
    ---------------------------------------------------------------------------------------------
    gulag_name              = db.storage[npc:id()].gulag_name,                                 --// string  - имя гулага NPC
    ---------------------------------------------------------------------------------------------
    loaded_gulag_name       = db.storage[npc:id()].loaded_gulag_name,                           --// string  - имя гулага NPC
    ---------------------------------------------------------------------------------------------
    loaded_ini_filename     = db.storage[npc:id()].loaded_ini_filename,                         --// string  - имя файла логики
    ---------------------------------------------------------------------------------------------
    ini_filename            = db.storage[npc:id()].ini_filename,                                --// string  - имя файла логики
    ---------------------------------------------------------------------------------------------
    stype                   = db.storage[npc:id()].stype,                                        --// number - тип схемы логики  0-4 из файла modules
    ---------------------------------------------------------------------------------------------
    zoneguard               = db.storage[npc:id()].zoneguard,                                   --// видимо поле для охранников - тип значения неизвестен
    }
    return tMgr[type]
end

 

 

Смысловую суть полей можно понять обратившись к файлам xr_схема.script - именно в них и происходит заполнение storage.

Изменено пользователем Garry_Galler
Ссылка на комментарий

Кто-нибудь может нормально объяснить про STATE_Write и STATE_Read, а то как ими нормально пользоваться я не понимаю. К примеру, я через STATE_Write получаю нет-пакет серверного объекта, дописываю туда свои данные, через STATE_Read сохраняю с указанием нового размера пакета. Однако новые данные не сохраняются. Кто-нибудь объяснит почему?

Ссылка на комментарий

Real Wolf

Однако новые данные не сохраняются.

Часом не в онлайне пытался это делать?

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Real Wolf,

перечитываю твой предыдущий пост и никак не могу понять, что именно ты пытаешься сделать. Какие такие новые данные? Что за новый размер? Такое ощущение, что ты какой-то ересью пытаешься заниматься. Показал бы код что-ли. Только не здесь. Запости вопрос в ковырялке.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

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

C++ class CScriptXmlInit {
    CScriptXmlInit ();

    InitSpinText(string, CUIWindow*); --окошко где выбирается текстовый параметр, а вот как туда текст сообразить я пока не разбирался
    InitTab(string, CUIWindow*); --инициализирует панель закладок (после полного разбора создания закладок, я убедился, что при должном использовании можно сделать что-нибудь интересное, главное фантазия), количество самих закладок неограничено, закладки делаются приаттачиванием к основному окну (желательно делать свой класс для каждой закладки, конечно, если они разные)
    InitStatic(string, CUIWindow*); --одна из самых распространенных функций, название говорит само за себя
    InitList(string, CUIWindow*); --какой-то список, до конца не понял
    InitTrackBar(string, CUIWindow*); --не проверял, но вроде горизонтальный ползунок(пример: установка громкости звука в опциях а так же множество видео настроек)
    InitSpinFlt(string, CUIWindow*); -- то же что и InitSpinText только там числа с одним знаком после запятой(может можно как то изменить, например при описании xml файла, и там где-то пошариться)
    ParseShTexInfo(string); --нигде не используется 
    InitLabel(string, CUIWindow*); --метка, интереса скорее всего не представляет, но используется не так редко
    InitSpinNum(string, CUIWindow*); -- то же что и InitSpinFlt, числа целые
    InitMapList(string, CUIWindow*); --список карт, применяется в окне нового сервера, возможно для изобретательных скриптеров может будет полезен и в сингле
    ParseFile(string); --чтение параметров из файла папки ...\gamedata\config\ui (например "ui_my_test_window.xml")
    InitCDkey(string, CUIWindow*); --поле ввода CD ключа в окне сетевой игры
    InitKeyBinding(string, CUIWindow*); --при описании в xml файле куча тегов... так и не смог запустить
    InitMMShniaga(string, CUIWindow*); --увеличительное стекло в главном меню
    InitWindow(string, number, CUIWindow*); --видимо инициализация пустого окна применяется один раз (или два)
    InitEditBox(string, CUIWindow*); --окошко редактирования текста
    InitCheck(string, CUIWindow*); --"галочка", используется в основном вне самого процесса игры (настройки)
    InitAutoStaticGroup(string, CUIWindow*); --используется в ui_game_over.script... что то связанное с текстом
    InitScrollView(string, CUIWindow*); --неуверен но вроде как область прокручивание колесиком мыши 
    InitMapInfo(string, CUIWindow*); --информация о карте(описание) в окне создания нового сервера, применяется один раз только там
    InitServerList(string, CUIWindow*); --список серверов, детально не разбирал
    Init3tButton(string, CUIWindow*); --инициализация трехступенчатой кнопки(кароче обычная кнопка :))
    InitAnimStatic(string, CUIWindow*); --анимация, смотрите пример в файле ui_mp_main.script и его описании ui_mm_mp.xml (для красивого оформления окна :))
    InitFrameLine(string, CUIWindow*); --небольшое окошечко-текстура, обычно окончание какого либо поля для текста, интерес представляет лишь для красоты
    InitComboBox(string, CUIWindow*); --инициализация выпадающего списка(пример: выбор статического или динамического освещения в опциях игры)
    InitButton(string, CUIWindow*); --нигде не используется (видимо замещено Init3tButton'ом)
    InitFrame(string, CUIWindow*); --создание фона с рамкой(см. описания xml файлов) наподобии InitStatic но из множества текстур
};

 

Возможны неточности в описании.

Изменено пользователем Desertir
  • Полезно 1

ТЧ 1.0004. SAP и Trans mod

github

Ссылка на комментарий

Desertir,

а для чего класс то предназначен и что вообще с ним делать? Из поста совершенно не ясно.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

malandrinus

ИМХО, посты-толковалки типа Desertir приносят больше вреда, чем пользы.

Кроме перечисления и 'типа, чего-то, но не проверял и наверное ...' по сути тавтология.

К примеру:

InitStatic(string, CUIWindow*); --одна из самых распространенных функций, название говорит само за себя
- ну очень "внятно" для тех, кто может даже и может перевести 'static', но ни к чему применить понять это понятие не знает. :-(

 

Не берусь сейчас (или вообще) толковать класс (и со временем напряженка и не осмеливаюсь называться 'толкователем'), но хотя бы банальное на скорую руку может выглядеть хотя бы так:

 

CScriptXmlInit() - класс-конструктор (как всегда доступен в виде глобальной функции). Предназначен для создания окон на базе xml-файлов. Ресультатом функции является объект-заготовка ('userdata').

 

ParseFile(string) --/ метод, распарсивающий (разбирающий) исходный xml-файл (string) в объект класса, что позволяет к полученным элементам объекта применять различные методы.

Элементы результирующего объекта получают названия/имена соответствующие тэгам разобранного xml-файла и все дальнейшие методы применяются к элементам с соответствующими 'тэговыми' именами.

Различные параметры (координаты, расцветка,тексты,шрифты,...), заданные тэгами xml-файла наследуются соответствующими элементами при их инициализации методами класса.

 

InitStatic(string, CUIWindow*) --/ метод, создающий обычную (статичную) область. Параметром является название (стринг) тэга из xml-файла. Применяется, например, для организации различных строк текста/заголовков, отображения текстур/картинок/иконок.

 

InitButton(string, CUIWindow*) --/ метод, создающий область обычной 'кнопки', имещую одно визуальное состояние, т.е. вид кнопки не изменяем.

 

Init3tButton(string, CUIWindow*) --/ метод, создающий область обычной кнопки, имеющую три визуальных состояния (не активна, в фокусе, нажата).

 

InitCheck(string, CUIWindow*) --/ метод, создающий область 'чек-бокс' (кнопка-галочка). Может принимать два фиксированных состояния: отмечена/не отмечена.

 

InitTab(string, CUIWindow*) --/ метод, создающий область (табулятор), которая объединяет несколько вложенных областей. Применяется для создания окна с закладками.

 

InitList(string, CUIWindow*) --/ метод, создающий область (листинг), в котором организуется список из строк, являющихся интерактивными элементами. При большом кол-ве элементов (превышающем размеры выделенной области листинга) используется совместно с методом InitScrollView, отображающем полосу прокрутки (скроллинг).

...

и т.д.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Ну да описание детское, но хоть какое-то, я вот на свой вопрос вообще ответа не получил. Делал описание для себя.

Пожалуйста, malandrinus, редактируй как лучше для понимания обществом ;)

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

Изменено пользователем Desertir

ТЧ 1.0004. SAP и Trans mod

github

Ссылка на комментарий

Desertir

Мой пост не преследует цель 'покритиковать', она совершенно иная.

Этот топик все же имеет название "Справочник ..." и предназначен и для для опытных (но забывчивых) и начинающих модмейкеров.

Твоя 'проба пера' вполне была бы уместна в топиках по ковыряниям в кодах ..., но никак не в справочном топике, по которому многие сверяют свои познания и набираются знаний/навыков.

В тему вспоминается басня Крылова, когда слепые изучали наощупь слона и у каждого он был то лопухом/колонной/змеей/..., в зависимости от того, что и как ощупывал слепец (ухо/ногу/хвост/...). Если на базе их описаний попытаться составить мнение о 'что-же такое слон', но картина выходит далекой от реалии.

Так и с подобными описаниями 'для себя и наскоро', которые для других скорее шоры навесят, чем откроют суть (примечание: мой вариант тоже близок к подобному!).

Все же иногда лучше не 'начинать' подобным образом и будет 'Ничего', чем ложное/пустое ... (ИМХО). Самостоятелная попытка познать неизвестное в подобных случаях скорее принесет бОльшую пользу, чем трата времени на чтение и попытку понять пустое/искаженное толкование.

 

Бум надеяться, что у malandrinus'а появится время, возможность и желание свести подобные посты в нечто достойное 'Справочника'. :-)

Для меня, это основой топик, из-за которого заглядываю на портал.

 

 

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Garry_Galler,

Выкладываю небольшой разбор содержимого полей таблицы db.storage

спасибо за вклад в тему! Очень полезная информация. Описание только движковых классов/функций, хоть и не закончено, но постепенно себя исчерпывает. Между тем остаётся немерянный пласт скриптовых наслоений, которые в сущности являются частью движка, поскольку используются уже поколениями модостроителей практически без изменений. Вот как минимум механизмы логики относятся к этому разряду. Их тоже можно было бы описать здесь.

 

 

Artos,

по мне так лучше, если бы писали здесь статьи хоть как-то, пусть и криво. Почистить и упорядочить в конечном счёте можно, если есть что чистить и упорядочивать. А последнее время вижу только смесь стола заказов и отделения ковырялки.

 

Разумеется, крайне желательно придерживаться примерно такого шаблона изложения (применительно к классам):

1. Общее назначение класса. В объёме одного абзаца или даже предложения объяснить, зачем вообще нужен данный класс. Какой объект он описывает или что можно сделать с его помощью. В случае с CScriptXmlInit это могло бы выглядеть таким образом.

 

Класс CScriptXmlInit предназначен для создания объектов окон (или объектов пользовательского интерфейса) на основе описания, заданного XML. Выгод от использования данного класса может быть несколько:

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

- возможность задать свойства окон, недоступные для изменения скриптом. К примеру, так можно задать перенос текста в текстовых полях.

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

 

2. Формальное описание. Примеров таких описаний я наплодил достаточно много. Я предпочитаю некий псевдо C++. В данном случае может выглядеть так.

 

class CScriptXmlInit {
    CScriptXmlInit (); // конструктор, как и для большинства других классов соответствует глобальной функции CScriptXmlInit 

    void ParseFile(string <имя XML файла>); // прочитать файл с описанием окна
    // инициализировать (не создать) окно базового типа, родительское не задано
    bool InitWindow(string <имя тега с описанием>, int index, CUIWindow* <окно для инициализации>);
    // создать окно типа CUIStatic, статический элемент
    CUIStatic* InitStatic(string <имя тега с описанием>, CUIWindow* <родительское окно>); 
     // создать поле для редактирования текста
    CUIEditBox* InitEditBox(string <имя тега с описанием>, CUIWindow* <родительское окно>)
    // и т.д.
}

 

3. Общие комментарии к описанию.

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

- Только один метод работает не так. Это метод InitWindow, который предназначен для инициализации самого родительского окна. Обращаю внимание, что этот метод не создаёт окно, а только задаёт его параметры (к примеру размеры). Ссылка на уже существующее окно, требующее инициализации, передаётся третьим параметром.

- Все методы принимают аргумент - имя тега, содержащего описание окна. Формат тега, дополнительные теги внутри него и атрибуты тега зависят от создаваемого окна. Их полное описание выходит за рамки данной статьи =(

 

4. Примеры использования. Например так.

    local xml             = CScriptXmlInit()
    xml:ParseFile        ("ui_game_over.xml")
    xml:InitWindow        ("main",0,self) -- здесь self - это ссылка на экземпляр диалога - окна верхнего уровня (не имеющего родителя)
     
    local st             = xml:InitStatic("background", self) -- создать на диалоге статический элемент на основе описания из тега "background"
    self.scroll_view     = xml:InitScrollView("scroll", st) -- создать на диалоге выпадающий список, описанный тегом "scroll"

 

К сожалению для класса CScriptXmlInit этого будет недостаточно, поскольку за каждым методом стоит ещё и описание всех сопутствующих тегов и атрибутов тегов, коих могут быть десятки. В целом же класс самоочевиден. Именно поэтому я его не описывал.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

malandrinus

Т.к. топик, по моему мнению, все же не подразумевает полемику, да и сам ты пишешь о 'смеси стола заказов и отделения ковырялки', вероятно не стОит затевать обмен мнениями. Но все же пару моментов прокомментирую.

 

1. Для многих начинающих модмейкеров подобные этому топики и статьи на вики-сайтах становятся учебниками и именно справочниками ... Нередко в разных топиках и на других порталах можно читать "ответы" от уже "наученых" с пояснялками-обосновалками на "так написано" или "а я это прочитал". Поэтому твоя фраза: "... по мне так лучше, если бы писали здесь статьи хоть как-то, пусть и криво" аукается потом не раз ... т.к. многие принимают "хоть как-то, пусть и криво" как руководство к действию, а не осмыслению.

Наиболее удобной (ИМХО) формой подобного топика было бы его разделение на два: собственно справочник с готовыми и статьями/разделами и топик с черновиками, вопросами, пояснениями-трактовками, полемикой, ...

 

2.

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

'Правильность' - понятие все же относительное, тем более в подобном вопросе (какой метод правильнее применять). Можно назвать немало ситуаций, когда применение скриптового метода будет 'не менее, и даже более правильным'. :-)

Мало кто уделяет дизайну должное внимание но ... если принять во внимание, что метод XML расчитан в основном на разрешение 4:3, и еще позволяется 16:10 дублированием уже имеющегося, то для немало уже появившихся ноутбучных экранов с их 16:9, 15x9 или 5x4 применение XML метода становится похоже на "взять болванку и обработать топором и рашпилем".

 

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

'Правильность' - понятие все же относительное, тем более в подобном вопросе (какой метод правильнее применять). Можно назвать немало ситуаций, когда применение скриптового метода будет 'не менее, и даже более правильным'. :-)

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

 

Мало кто уделяет дизайну должное внимание но ... если принять во внимание, что метод XML расчитан в основном на разрешение 4:3, и еще позволяется 16:10 дублированием уже имеющегося, то для немало уже появившихся ноутбучных экранов с их 16:9, 15x9 или 5x4 применение XML метода становится похоже на "взять болванку и обработать топором и рашпилем".

Проблема с разными разрешениями при работе с хмл надуманная. В работе с хмл нет завязки на разрешение 4:3. Что мешает сделать несколько хмл с разными именами и загружать нужный для данного разрешения.

 

А с учетом нижесказанного, так и вообще.

 

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

Собственно да, хочешь тот же многострочный статик - только хмл

Ссылка на комментарий

abramcumner

Все же стОит снимать шоры и не считать свое мнение самым правильным ....

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

Ну а дизайнер - именно риcует, а LTX/XML и пр. подобное - удел кодеров. Или у нас уже дизайнеры освоили XML-форматы и русуют ими? ;-)

 

Проблема с разными разрешениями при работе с хмл надуманная. В работе с хмл нет завязки на разрешение 4:3

Действительно нет ... вот только все исходные XML'ки (все значения параметров) заточены под именно это разрешение и 'широкоформатникам' часто приходится играть на том, что дизайнер нарисовал, а у кодера руки дошли ... Адаптации модов под 'широкоформатники' (точнее их отсутствие) - пример тому, что модмейкеры в одну из последних очередей вспоминают о 'инако-форматниках'.

Не проще ли порой, не штамповать кучку XML'ек, а в самом скрипте динамически подстроить именно так, как нарисовал дизайнер? Иль ты считаешь, что на 1024x768 (это те же 4:3) задуманное будет тем же, что и на 1600x1200, хотя бы с выбором шрифтов?

 

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Artos

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

Правда?! Нет, в самом деле? Так это обнадёживает. Я то был искренне уверен, что всем глубоко по барабану.

 

Наиболее удобной (ИМХО) формой подобного топика было бы его разделение на два: собственно справочник с готовыми и статьями/разделами и топик с черновиками, вопросами, пояснениями-трактовками, полемикой, ...

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

 

По поводу XML. Я написал:

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

не вижу, что здесь неправильного. Я написал "почти", что вполне покрывает те единичные случаи, когда элементы настолько динамичны, что даже создавать их через XML смысла нет. Но эти случаи действительно единичны. И в общем основной тезис - "модостроители не знают возможностей XML" (почти все). Если человек знает все возможности, то ему мои рассуждения побоку, сам решит.

 

Не проще ли порой, не штамповать кучку XML'ек, а в самом скрипте динамически подстроить именно так, как нарисовал дизайнер?

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

 

Иль ты считаешь, что на 1024x768 (это те же 4:3) задуманное будет тем же, что и на 1600x1200, хотя бы с выбором шрифтов?

Таки да, будет тем же, поскольку в сталкере для интерфейса используются виртуальные координаты, и экран всегда имеет размеры 1024х768 вне зависимости от физического разрешения. Поэтому достаточно только создать варианты конфигов для отдельных пропорций. А учитывая доминирование всего двух пропорций задача становится не такой уж и неподъёмной. По большому счёту, для нестандартных пропорций можно мириться с небольшими искажениями.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Полтергейст,

этот колбек (callback.zone_enter) работает только для одного класса ce_script_zone. Движковый сет для этого класса имеет имя SCRPTZN, имеется готовая секция с именем "script_zone". Из всех трёх игр этот объект используется только для ТЧ для Арены. Собственно там и можно посмотреть пример использования этого колбека. Это файл xr_zones.script

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
  • Куратор(ы) темы:

×
×
  • Создать...