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

[SoC] Ковыряемся в файлах


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

Да, я об этом упомянул, что касается дополнительных локаций :)... Кстати, забыл закомментить в середине сигнальную функцию <amk.send_tip2(obj:name(), nil, 10>, модеры, исправьте этот недостаток вместе с этим постом ;)...

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

=VENOM=, немного покритикую ;-)

 

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

2. Числовые значения для class_id могут в модах и изменяться по мере добавления новых объектов. Не стОит привязываться к конкретному значению (ИМХО) ведь можно использовать вместо 83 -> 'clsid.inventory_box'.

3. Почему то принято итерацию проводить до 65535, хотя 65535 - это уже технологический (временный) индекс и такого объекта в игре по сути не может быть. Мелочь, но повторяется многими ...

 

Вот вариант, который может быть использован не зависимо от мода и известных локаций:

function get_invbox_by_level_and_name(sBoxName, sLevelName_for_Box)
 for id=1,65534 do
   local seObj = alife():object(id)
   if seObj and seObj:clsid() == clsid.inventory_box and seObj:section_name() == "inventory_box" and seObj:name() == sBoxName then
     local idGv = seObj.m_game_vertex_id --/ гейм-вертекс ящика
     if idGv and game_graph():valid_vertex_id(idGv) then --/ проверяем валидность гейм-вертекса
       local oVertex = game_graph():vertex(idGv) --/ глобальный вертекс ящика
       if oVertex then
         local idLevel = oVertex:level_id() --/ (числовой) индекс уровня/карты
         if idLevel then
           local sLevelName = alife():level_name(idLevel) --/ имя уровня/карты
           if sLevelName == sLevelName_for_Box then --/ это заданный уровень?
             news_manager.send_tip(db.actor, sBoxName, 0, "default", 8000) --/ сообщение на игровой экран
             return seObj --/> серверный объект искомого ящика
           end
         end
       end
     end
   end
 end
end

- его конечно можно подоптимизировать 'по месту', убрав излишние строки/перепроверки и закешировав результаты, но это уже ... забота модмейкера. :-)

 

P.S. О, пока готовил пост уже и malandrinus о том же высказался.

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

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

Ссылка на комментарий
Вообщем создаю новую группировку по уроку, раньше отлично получалось но сейчас мучает вот такой вылет:

Что-то, видимо, не так со спавном лута в трупе. Проверяй.


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

Artos, неплохо, но я стараюсь вперёд выставлять числовые сравнения, отсеивая строковые в последнюю очередь:

cmp eax, ebx всегда быстрее, чем repe cmps str1, str2 ;)...

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

=VENOM=, аналогично, но(!) суть не в самой оптимизации, а в алгоритме. Это всего лишь заготовка(!) для тех, кто или использует готовенькое или не прочь доковырять под себя и свои нужды. Да и не бывает все всегда однозначно!

 

Я же специально написал: оптимизация забота модмейкера! А если ух озабочен оптимизацией, то и делать это нужно всерьез и конкретно.

Если подобный скрипт используется в 'разовых' алгоритмах типа выдачи тайника - то нет смысла заморачиваться.

Для циклов/схем - это особый разговор и я не зря упомянул о 'кешировании'.

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

Так что это уже скорее вопрос 'религии' модмейкера, т.е. кто к чему привык и что предпочитает. Я, как правило, предпочитаю 'оптимальную универсальность', перед 'оптимизированной частностью'.

 

Вот вариант, предназначенный для циклов, т.е. когда при первом запросе производится создание массива ящиков, а все последующие - простая выборка из массива:

local tInvBoxes = {} --/ массив Id для ящиков (по локациям)

function get_invbox_by_level_and_name(sBoxName, sLevelName_for_Box)
 local idInvBox = tInvBoxes[sLevelName_for_Box] and tInvBoxes[sLevelName_for_Box][sBoxName]
 if not idInvBox then --/ заданный ящик еще не был найден
   local sim = alife() --/ кешируем заодно уж и функцию
   for id=1,65534 do
     local seObj = sim:object(id)
     if seObj and seObj:clsid() == clsid.inventory_box and seObj:section_name() == "inventory_box" then
       local idGv = seObj.m_game_vertex_id --/ гейм-вертекс ящика
       if idGv and game_graph():valid_vertex_id(idGv) then --/ проверяем валидность гейм-вертекса
         local oVertex = game_graph():vertex(idGv) --/ глобальный вертекс ящика
         if oVertex then
           local idLevel = oVertex:level_id() --/ (числовой) индекс уровня/карты
           if idLevel then
             local sLevelName = sim:level_name(idLevel) --/ имя уровня/карты
             if not tInvBoxes[sLevelName] then
               tInvBoxes[sLevelName] = {} --/ создаем подмассив для локации
             end
             tInvBoxes[sLevelName][seObj:name()] = id --/ запоминаем идентификатор найденного ящика
             if seObj:name() == sBoxName then
               idInvBox = id --/ запоминаем идентификатор искомого ящика
               news_manager.send_tip(db.actor, sBoxName..":"..tostring(id), 0, "default", 8000) --/ сообщение на игровой экран (один раз!)
             end
           end
         end
       end
     end
   end
 end
 return idInvBox and alife():object(idInvBox) --/> серверный объект искомого ящика или nil
end

 

- и это опят все же 'заготовка', т.к. немало чудачеств еще стОит учесть.

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

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

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

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

Приветствую!

Что может значить сей вылет?

 

Expression    : assertion failed
Function      : I:\xray-svn\editors\ShaderEditor\GameMtlLib_Editor.cpp
File          : I:\xray-svn\editors\ShaderEditor\GameMtlLib_Editor.cpp
Line          : 58
Description   : p_it==material_pairs.end()

Происходит только при загрузке быстрого сохранения возле объекта к которому я прописал новый материал.

Его так-же наблюдаю при сохранении/и ковырянии gamemtl в SE.

 

Мой архив

Сталкером не занимаюсь.

Ссылка на комментарий
amik, да вроде похоже на то, что ты не назначил своему материалу какой(ие) материал(ы) как пару или другим свой. Каждому материалу по идее нужно в паре все остальные прописывать. Изменено пользователем Шип
Ссылка на комментарий

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

В другом месте у меня тоже есть другой сделанный материал, делаю все тоже самое все нормально, но тут :fie: ...

Мой архив

Сталкером не занимаюсь.

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

Привет всем. Есть вопрос не большой. Я тут сделал миноискатель, ведь мины - те же аномалии... Прописал ему нахождение мин, но почему то не работает... Не "пикает" :)

Уже и в Зенобиан моде смотрел, их конфиг ставил - всё равно ничего не происходит... Может просто создание детектора-миноискателя недостаточно? Может еще что надо?

Вот конфиг миноискателя:

[mine_detector]:identity_immunities
GroupControlSection    = spawn_group
discovery_dependency =
$prefetch             = 32
class                = D_SIMDET
cform                = skeleton
visual                = equipments\item_datchik3.ogf
description            = enc_mine_detector
radius                = 10
buzzer_radius        = 1.5
noise                = detectors\geiger_noise_loop
buzzer                = detectors\DA-2_alarm_loop
slot                = 9
ef_detector_type    = 1
inv_name            = mine_detector
inv_name_short        = mine_detector
inv_weight            = 0.78
inv_grid_width        = 1
inv_grid_height        = 1
inv_grid_x            = 60
inv_grid_y            = 66
cost                = 8500
belt                = true
default_to_ruck        = true

;описание распознаваемых детектором зон

;Мины
zone_class_1        = zone_mine_field
zone_sound_1_        = detectors\DA-2_beep1
zone_min_freq_1        = 0.1;0.5
zone_max_freq_1        = 40
zone_map_location_1     = anomaly_bald_location

 

 

P.S. еще у меня стоят партикли Амика - там мина невидимая... Может из-за этого?

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

У тебя правильно составлен конфиг. Просто загляни в файл gamedata\config\misc\zone_minefield.ltx и проверь, чтобы параметр был указан вот так: visible_by_detector = on, и всё должно заработать. Этот параметр как раз и отвечает за то, обнаруживает детектор эту аномальную зону или нет.

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

Здравствуйте! А можно ли запретить использование оружия во время езды на машине в сталкере? Просто камера БТР настроена так, что вид сверху, а пистолет можно достать, и вид, будто Меченый сидит на БТРе и стреляет.

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

Подскажите пожалуйста мне не посвященному как зареспавнить типов из новой групировки, как в срп или по одному (я не разобрался с character_desc_локация.xml). Спасибо

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

Подскажите пожалуйсто это можно исправить? Если да, то как?

Expression : Ran out of memory

Function : CRender::texture_load

File : E:\stalker\patch_1_0004\xr_3da\xrRender\Texture.cpp

Line : 356

Description : D3DXCreateTextureFromFileInMemoryEx ( HW.pDevice,S->pointer(),S->length(), D3DX_DEFAULT,D3DX_DEFAULT, IMG.MipLevels,0, IMG.Format, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT, D3DX_DEFAULT, 0,&IMG,0, &T_sysmem )

Arguments : c:\my game$\s.t.a.l.k.e.r\gamedata\textures\ui\ui_mainmenu.dds

 

Такой вылет всё время на динамическом освещении, вместо ui_mainmenu.dds может быть любая другая текстура, вылет рандомный, где то через 1-3 минуты игры.

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

Ulman,

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

Ссылка на комментарий
Подскажите пожалуйста мне не посвященному как зареспавнить типов из новой групировки

Есть же отдельная тема по НПСам. Возьми и почитай. Там достаточно все ясно написано. И тема спавна тоже есть.

 


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

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

FANAT.gif

Мой канал на ютабчике... / Недельки из жизни фаната STALKER'a / Клуб 'Фанат Отчуждения'

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

Всё в порядке, всё нормально, я беру тебя с собой, я беру тебя с собой. В тёмный омут головой.(с)Смысловые Галлюцинации

Ссылка на комментарий
Т.о. респавненный объект не получит имя 'escape_lager', а получит именем типа 'escape_lager23456' и, если работа завязана на конкретном имени объекта (а таких немало) - она (работа) уже до конца игры не будет задействована в случае гибели и исчезновения/удаления неписи. В этом случае только спавн по заведомо известной секции из all.spawn'а можно 'воссоздать' объект с нужным именем. Штатный респавн подобным не занимается.

Конечно попахивает быдлокодерством, но что мешает нам наплодить потомков в конфиге типа

[escape_lager_1]:escape_lager

[escape_lager_2]:escape_lager

[escape_lager_3]:escape_lager

[escape_lager_4]:escape_lager

[escape_lager_5]:escape_lager

...

[escape_lager_n]:escape_lager

 

 

Добавлено через 19 мин.:

Как с помощью net_packet() поставить "restrictor_type = 2" для всех аномалий?

В цикле выбрать все аномалии из объектов, и с помощью нижеследующих функций перепаковать аномалии.

for i=....
   local obj = alife():object(i)
   if obj and --тут поставить условие, шобы отбирались только аномалии
     local data = read_anomaly_params(obj)
     data.restrictor_type=2
     --учти что перепаковывать можно объекты находящиеся в оффлайне, иначе эффекта ты не увидишь.
     write_anomaly_params(data,obj)
   end
end

function read_anomaly_params(sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  sobj:STATE_Write(stpk)
  sobj:UPDATE_Write(uppk)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  local t={}
  t.gvid=stpk:r_u16()
  t.obf32u1=stpk:r_float()
  t.obs32u2=stpk:r_s32()
  t.lvid=stpk:r_s32()
  t.oflags=stpk:r_s32()
  t.custom=stpk:r_stringZ()
  t.sid=stpk:r_s32()
  t.obs32u3=stpk:r_s32()

    local shape_count = stpk:r_u8()
    t.shapes={}
    for i=1,shape_count do
        local shape_type = stpk:r_u8()
        t.shapes[i]={}
        t.shapes[i].shtype=shape_type
        if shape_type == 0 then
            -- sphere
            t.shapes[i].center = stpk:r_vec3()
            t.shapes[i].radius = stpk:r_float()
        else
            -- box
            t.shapes[i].v1 = stpk:r_vec3()
            t.shapes[i].v2 = stpk:r_vec3()
            t.shapes[i].v3 = stpk:r_vec3()
            t.shapes[i].offset = stpk:r_vec3()
        end
    end
  t.restrictor_type = stpk:r_u8()
  t.max_power = stpk:r_float()
  t.owner_id = stpk:r_s32()
  t.enabled_time = stpk:r_s32()
  t.disabled_time = stpk:r_s32()
  t.start_time_shift = stpk:r_s32()
  t.offline_interactive_radius = stpk:r_float()
  t.artefact_spawn_count = stpk:r_u16()
  t.artefact_position_offset = stpk:r_s32()
  t.last_spawn_time_present = stpk:r_u8()
  return t
end

function write_anomaly_params(t,sobj)
  local stpk=net_packet()
  local uppk=net_packet()
  stpk:w_u16(t.gvid)
  stpk:w_float(t.obf32u1)
  stpk:w_s32(t.obs32u2)
  stpk:w_s32(t.lvid)
  stpk:w_s32(t.oflags)
  stpk:w_stringZ(t.custom)
  stpk:w_s32(t.sid)
  stpk:w_s32(t.obs32u3)


    stpk:w_u8(table.getn(t.shapes))
    for i=1,table.getn(t.shapes) do
        stpk:w_u8(t.shapes[i].shtype)
        if t.shapes[i].shtype == 0 then
            stpk:w_vec3(t.shapes[i].center)
            stpk:w_float(t.shapes[i].radius)
        else
            stpk:w_vec3(t.shapes[i].v1)
            stpk:w_vec3(t.shapes[i].v2)
            stpk:w_vec3(t.shapes[i].v3)
            stpk:w_vec3(t.shapes[i].offset)
        end
    end

  stpk:w_u8(t.restrictor_type)
  stpk:w_float(t.max_power)
  stpk:w_s32(t.owner_id)
  stpk:w_s32(t.enabled_time)
  stpk:w_s32(t.disabled_time)
  stpk:w_s32(t.start_time_shift)
  stpk:w_float(t.offline_interactive_radius)
  stpk:w_u16(t.artefact_spawn_count)
  stpk:w_s32(t.artefact_position_offset)
  stpk:w_u8(t.last_spawn_time_present)
  local size=stpk:w_tell()
  local size1=uppk:w_tell()
  stpk:r_seek(0)
  uppk:r_seek(0)
  sobj:STATE_Read(stpk,size)
  sobj:UPDATE_Read(uppk)
end

 

118 101 110 105 44 32 118 105 100 105 44 32 118 105 99 105
Ссылка на комментарий

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

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

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

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

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

Войти

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

Войти
×
×
  • Создать...