Всем привет!
Короче вопрос такой, почему логика у НПСа, заспавненного скриптом, не работает?
Вот его секция:
[monolith_sniper_limansk]:stalker
$spawn = "respawn\monolith_sniper_limansk_01"
character_profile = monolith_sniper_limansk
spec_rank = regular
community = monolith
cfg = scripts\monolith_sniper_limansk.ltx
в логике при убийстве НПСа выдается инфопоршень + сам НПС долже сидеть на точке и быть снайпером.
НО однако после спавна скриптом ничего не происходит, НПС тупо бродит по зоне.
вопрос?
почему умина ни получица распаковать Level
----------------------------------------------------------------------------------------------------------------
E:\S.T.A.L.K.E.R\level_editor\converter -level l01_escape -out 01_escape -mode le
log statted
path $maps$ does not exist
path $objects$ does not exist
; фильтр для зашитых в геометрию декалей
;
; filter to detect compiled-in wallmarks (level.wallmarks is redundant)
[2xxx_wallmark_shaders]
effects\wallmark
effects\wallmarkset
effects\wallmarkblend
effects\wallmarkmult
; к MU-моделям можно подклеивать CFORM-кусочки только с
; перечисленными материалами.
;
; Only CFORM-cuts with game materials listed below will be merged.
[2xxx_fake_mu_gamemtls]
materials\bush
materials\tree_trunk
; в _fake.object будут попадать лишь CFORM-кусочки
; с перечисленными материалами.
;
; _fake.object will contain only CFORM-cuts with
; game materials listed here.
[2xxx_fake_gamemtls]
materials\fake
materials\death
; кусочки с такими engine_shader'ами нельзя приклеивать к чему-либо
;
; geometry cuts with engine shaders listed below cannot be merged
[2xxx_inadhesive_shaders]
effects\water
effects\waterstuden
effects\waterryaska
effects\lightplanes
;selflight
; далее идут независимые от профиля настройки (лучше их не трогать).
;
; profile-independent settings follow (it is better to not touch these).
[settings]
debug_texture = temp\temp_purewhite1 ; для отладки. не трогать.
fake_gamemtl = materials\fake ; забыл, гг
ladders_gamemtl = materials\fake_ladders; лестницы
ghost_eshader = effects\lightning ; для подсветки невесомой геометрии (с -dbgcfrm)
; здесь указывается текстура и, возможно, шейдеры для восстановленной из CFORM геометрии
; = <текстура>[, [, ]]
;
; presets to set shaders/material for CFORM geometry
; = [, [, ]]
[collider_presets]
materials\bush = trees\trees_fuflo, def_shaders\def_trans, flora\flora_collision
materials\bush_sux = trees\trees_fuflo, def_shaders\def_trans, flora\flora_collision
materials\tree_trunk = trees\trees_bark_a_01, def_shaders\def_trans, flora\flora_collision
materials\fake_ladders = prop\prop_fake_ladder, def_shaders\def_vertex
materials\death = prop\prop_fake_dead, def_shaders\def_vertex, def_shaders\def_kolizion
materials\fake = prop\prop_fake_kollision, def_shaders\def_vertex, def_shaders\def_kolizion
materials\glass = glas\glas_temp, def_shaders\def_vertex, def_shaders\def_kolizion
materials\water_radiation = water\water_normal, def_shaders\def_vertex, def_shaders\def_kolizion
; для раскраски геометрии по game_material (с -dbgcfrm)
; = <текстура>
;
; to paint geometry according to game material (with -dbgcfrm option)
; =
[debug_cform_textures]
default = sign\sign_gerb
materials\asphalt = ston\ston_asfalt_b
materials\bricks = ston\ston_bricks3
materials\bush = trees\trees_fuflo ; если надо видеть фуфло
;materials\bush = tree\tree_fuflo ; в 3120 фуфло только такое
materials\cloth = andy\andy_btn_fake
materials\concrete = crete\crete_concrete_03
materials\death = prop\prop_fake_dead
materials\dirt = grnd\grnd_dirt1
materials\earth = grnd\grnd_zemlya2_iov
materials\earth_slide ; намеренно пустая строка
materials\fake ; намеренно пустая строка
materials\fake_ladders ; намеренно пустая строка
materials\flooring_tile = crete\crete_plitka2
materials\glass = glas\glas_temp
materials\grass = grnd\grnd_grass1
materials\gravel = grnd\grnd_dtr_iov
materials\metal = mtl\mtl_bayda_con
materials\metal_pipe = mtl\mtl_tubes7
materials\metal_plate = mtl\mtl_angar_a_b
materials\sand = grnd\grnd_sand
materials\setka_rabica = mtl\mtl_fence2n
materials\shifer = crete\crete_schiffer1
materials\stucco = crete\crete_stuccowall_iov
materials\tin = prop\prop_banka2
materials\tree_trunk = trees\trees_bark_a_01
materials\water = water\water_ryaska1
materials\water_radiation = water\water_ryaska1
materials\wood = wood\wood_jasik
materials\wooden_board = wood\wood_chipboard1
objects\glass ; намеренно пустая строка
; для замены имени карты (на диске) на более осмысленное (только без -out)
;
; to auto-rename some levels (works without -out option only)
[scene_names]
lev5_aztec = aztec
escape_koanyvrot = escape1114
level1_game = escape1154
level1_car = escape1154c
level2_game = agroprom1154
level2_car = agroprom1154c
=================================================
и fsconverter.ltx
Хотелось бы получить ответ от модератора(ов) раздела на вопрос:
"До какой степени безграмотность, лень и глупость в постах должны дойти в этом топике, чтобы модератор(ы) начали следить за соблюдением правил портала?"
Уже не просто спрашивать/отвечать ..., читать топик нет никакого желания.
То, что в этом топике задаются глупые, безграмотные и повторяющиеся много раз вопросы, означают лишь одно: пользователям лень перечитывать тему и что-то искать самим. За это модераторы никакой ответственности не несут.
Касательно самого раздела: буквально на днях поднимался вопрос по поводу его нынешнего состояния. Меры будут приняты.
Однако: (ИМХО) ответственность модераторов заключается конечно же не в нарушении правил самими пользователями, но и(!) не только в созерцании ... бардака.
Если пользователь неопытен - можно и поравить/подсказать/напомнить.
Если уперт - банометы и пр.меры никто у модераторов не отменял. Одного/двух лентяев-"граматеев" отправить на пару дней в R/O и чище будет и, как правило, желание читать и думать появляется ...
(сорри за оффтопик, но созерцать бардак уже нет терпения)
Несколько дней назад, на этот пост пытались ответить Stalk15 и тов. erlik.
Правда решение так и небыло найдено... Хотелось бы услышать ваше мнение
об этой проблемке.
ЦИТАТА:
Вобщем, трениро**5001b67681f3126adde4**da\xrGame\script_engine.cpp
[error]Line : 73
[error]Description :
[error]Arguments : LUA error: ...ое Издание\shoc\gamedata\scripts\task_manager.script:210: attempt to index field '?' (a nil value)[/code]
Что писал:
> В misc\task_manager:
[code]
;----------Trader--------------------------------------------------
;----------AleX MOD tasks----------
;-----------Monster Part------------
trader_find_monster_part_zombie_hands
[trader_find_monster_part_zombie_hands]
type = monster_part
community = actor
text = trader_find_monster_part_zombie_hands_text
description = trader_find_monster_part_zombie_hands_descr
parent = trader
target = mutant_zombie_hand, 2
reward_money = 300
reward_reputation = +5
reward_rank = 1
time = 172800
prior = 10[/code]
> В gameplay\storyline_info_taskmanager:
[code];---------Monster Part--------------
;---------trader--------------
;----------AleX MOD Tasks---------- trader_find_monster_part_zombie_hands_descr [/code]
> В text\rus\stable_task_manager_alex_mod:
[code] Притащить две руки зомби
Притащить две руки гражданского зомби
Тут недавно ко мне один сталкер-шаман заходил, оставил заказ на две руки гражданских зомби. Хрен его знает зачем ему эта дрянь... Вобщем, говорят у нас на Кордоне, видели несколько этих... Как только они сюда добрели - неизвестно. Ну, что берёшся?
Stalker_Alex333
Неплохо бы уточнять: строка, на которую ругается лог у тебя 'оригинальная' или же скрипт уже был модифицирован.
Если ругается на строку: self.task_info[id].enabled = p:r_bool() , то можно сказать следующее:
1. Никакие storyline_info_taskmanager, stable_task_manager_alex_mod, localization.ltx тут не виноваты.
2. Ошибка идет при считывании уже сохраненной игры. Добавлял ли ты свой новый квест ПОСЛЕ сэйва?
Если да - то в этом и кроется ошибка. Таск менеджер запоминает в сэйвах все квесты в игре и любое изменение в кол-ве или порядке следования запомненных квестов - приводит к фатальной ошибке при чтении сэйва. Т.е. (почти) любое изменение в наименованияъ/кол-вах заданий требует новой игры или спец.мер по адаптации старых сэйвов.
Если ошибка проявляется на новой игре - то поставь в 210-ую строку таск-менедэера вывод в лог считываемого идентификатора (id) квеста ... Возможно ты напортачил с компонентами имени своего квеста.
В строке/параметре: target = mutant_zombie_hand, 2 - точно ошибка. Цель может быть только в единственном числе.
СтОит помнить, что исходный таск-менеджер завязан на версии патча игры и для 1.0004 имеются особенности, по сравнению с 1.0005/6.
Я давно уже переделал на универсальный вариант + сжатый формат записи в сэйвы ... Именно оригинальный таск-менеджер очень прожорлив на объем в сторадже актра и не не замечен в аккуратности (мусора хранит немало).
6. Пишите грамотно! Посты типа "а я вот тоже падумал и ришил што хачу пааварить аб анамалиях и гыгыг манстярках хехе такии смишныи крысски гыгыгы" будут удаляться без предупреждения. Используйте знаки препинания, Заглавные буквы в предложениях, проверяйте свои посты на наличие пропусков букв и элементарных ошибок. Это культурный форум а не чат, где важнее всего скорость набора фраз.
Просишь о помощи, ждешь ответа на вопрос - уважай тех, кто читает твои опусы!
ешо один вопрос ?
умнея проблема. в со загрузчика без ошейник но когда я нажиму compile > build
очень много фалов textures ни хватит
There is no texture 'gamedata\textures\lod\lod_levels_l02_garbage_l02_garbage_lod0072.dds'
There is no texture 'gamedata\textures\lod\lod_levels_l02_garbage_l02_garbage_lod0072_nm.dds'
ERROR: Validate 'Scene Object' failed!
Capturing unused face...
Validation FAILED!
ERROR: Validation failed. Invalid scene.
Действительно, вся соль оказалась в старых сохранениях. И это очень обидно, т.к. перепроходить игру из-за новых квестов, мягко говоря не хочется...
Я заметил, вы упомнали о своей (облегченной) версии скрипта task_manager, ее можно где либо скачать?
Есть ли способ подключить новые квесты (как простые, так и более сложные) "динамически", без начала новой игры?
З.Ы. Каким способом в квесте, указать кол-во разыскиваемых ГГ предметов более одного?
Stalker_Alex333
Не задавай сразу несколько вопросов ... Портянку ответа писать не самое легкое и полезное ... :-)
1. Модифицированную версию таск-менеджера (task_manager.script) можно взглянуть в сборке Симбиона (ТЧ) в любом последнем инификсе.
Также делал специальные варианты для NLC6, т.н. минимод "Адаптер игровых патчей", в котором и таск- и диалог- менеджеры отвязаны от патчей игры и введена 'компрессия' данных и даже автопатчер (автоподстройка под установленный игровой патч) введена. Но ... что-о Сяк так и не ввел в мод ...
В принципе не сложно и оригинальный(ые) менеджер(ы) адаптировать по уже имеющимся вариантам.
2. Освежин немного в памяти алгоритм сохранок таск-менеджера. В принципе подключать новые квесты не сложно. Основное правило для старых сэйвов: имена квестов, которые были в игре и сохранены НЕ должны меняться. Также не должны меняться их поля 'type' и 'parent', т.е. то из чего расчитывается 'complex_type'.
Если используешь АМК-вариант таск-менеджера, то важны совпадения сохраненных в сэйве хешей.
При удалении/изменении старых названий/параметров квестов для совместимости можно вводить заглушки, которые должны обходить фатальные ошибки при отсутствии записей/квестов. Пример для хешей можно посмотреть в рудиментарном коде в сборке Симбион.
3. Т.к. параметр 'target' используется для ВСЕХ типов квестов/заданий и его чтение (т.е. содержание) жестко регламентировано исходным кодом то ... при желании указывать кол-ва потребуется изменить формат этого параметра.
СтОит помнить, что для некоторых типов по нему определяется (стори)идентификатор цели. Если ввести свою читалку-парсер этого параметра - то и кол-ва можно встроить в параметры заданий.
Но это уже мы ударяемся в собственно в разработку кодов, суть же: для указания количеств целевых предметов требуется доработка исходника.
Ну или банально - использовать не штатный таск-менеджер, а свои функции, которые определяют выполнение условий квеста.
При попытки адоптации болтов от Charsi, к NLC Начало 6.08 происходит вылет:
Expression : fatal error
Function : CScriptEngine::lua_error
File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp
Line : 73
Description :
Arguments : LUA error: ....-Тени Чернобыля\gamedata\scripts\bolt_binder.script:42: attempt to index field 'actor' (a nil value)
что это значит и как это исправить?Ссылка на болты от Charsi.
goust
Твой кусок лога говорит о том, что при появлении некоего болта в игре - объекта актора в игре или еще нет или уже нет.
Подобная ошибка возможна вероятнее всего при неправильной адаптации, когда вызов спавна болта происходит ранее создания клиентского объекта актора (db.actor). Версию, когда актор уже исчез из игры не рассматриваем, все же NLC - сингл.
Правильно исправить - подобрать инициализацию/спавн болтов только тогда, когда объект актор уже в игре.
Обойти фатальную ошибку можно и заплаткой типа:
function BBolt:net_spawn(data)
if db.actor and self.object:position():distance_to(db.actor:position()) < 2 then
table.insert( bolt_mod.new_bolt_id, self.object:id() )
end
return object_binder.net_spawn(self, data)
end
З.Ы. Каким способом в квесте, указать кол-во разыскиваемых ГГ предметов более одного? Stalker_Alex333
Но это уже мы ударяемся в собственно в разработку кодов, суть же: для указания количеств целевых предметов требуется доработка исходника. Artos
Если нет специального параметра "количество" - остаётся только "отдельное задание на каждый предмет". Разве в Сталкере нет штатных "вложенных заданий"? Но даже если таких нет - их можно эмулировать: на каждый предмет выдать отдельное задание и, плюс, выдать ещё одно задание, условием которого будет выполнение всех остальных заданий... ну и так далее.
Artos
Поставил твою заплатку и вылет:
Expression : fatal error
Function : CScriptEngine::lua_error
File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp
Line : 73
Description :
Arguments : LUA error: ...r.-Тени Чернобыля\gamedata\scripts\se_respawn.script:466: attempt to index field 'actor' (a nil value)
Вот se_respawn.script
--[[------------------------------------------------------------------------------------------------------------------
Respawner. Схема обновления популяции всего всего всего в симуляции.
by Stohe(Диденко Руслан)
--------------------------------------------------------------------------------------------------------------------]]
--function printf()
--end
local section_name = "respawn"
local i,k,v = 0,0,0
local idle_spawn_preset = {
seldom = 60*60*24,
medium = 60*60*12,
often = 60*60*3,
--seldom = 60*60*6,
--medium = 60*60*3,
--often = 60*60,
once = -100000
}
-- Список респавнеров, для сбора статистики
local respawners = {}
local respawners_by_parent = {}
----------------------------------------------------------------------------------------------------------------------
-- Разные полезные функции
----------------------------------------------------------------------------------------------------------------------
function r_bool(spawn_ini, section, line, default)
if spawn_ini:line_exist(section, line) then
return spawn_ini:r_bool(section, line)
else
return default
end
end
function r_str(spawn_ini, section, line, default)
if spawn_ini:line_exist(section, line) then
return spawn_ini:r_string(section, line)
else
return default
end
end
function r_num(spawn_ini, section, line, default)
if spawn_ini:line_exist(section, line) then
return spawn_ini:r_float(section, line)
else
return default
end
end
function r_2nums(spawn_ini, section, line, def1, def2)
if spawn_ini:line_exist(section, line) then
-- если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini
local t = parse_names(spawn_ini:r_string(section, line))
local n = table.getn(t)
if n == 0 then
return def1, def2
elseif n == 1 then
return t[1], def2
else
return t[1], t[2]
end
else
return def1, def2
end
end
function parse_names(s)
local t = {}
for name in string.gfind(s, "([%w_%-.\\]+)%p*") do
table.insert(t, name)
end
return t
end
function r_spawns(spawn_ini, section, line, sectSpawnProps)
if spawn_ini:line_exist(section, line) then
--' если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini
local t = parse_names(spawn_ini:r_string(section, line))
local n = table.getn(t)
local ret_table = {}
local k = 1
while k <= n do
local spawn = {}
spawn.section = t[k]
-- Проверяем что это не последняя запись
if t[k+1] ~= nil then
local p = tonumber(t[k+1])
-- проверяем что вторым числом задана вероятность, а не другая секция спавну
if p then
-- забиваем число
spawn.prob = p
k = k + 2
else
-- забиваем дефолт 1
spawn.prob = 1
k = k + 1
end
else
spawn.prob = 1
k = k + 1
end
table.insert(ret_table, spawn)
-- Вычитываем настройки секций респавна и кешируем их.
if sectSpawnProps[spawn.section] == nil then
local respawn_ini = system_ini()
local community = r_str(respawn_ini, spawn.section, "community", "nil")
local rank = r_str(respawn_ini, spawn.section, "spec_rank", "nil")
local check = true
local custom_data = r_str(respawn_ini, spawn.section, "custom_data")
if custom_data ~= nil then
local custom_data_ltx = ini_file(custom_data)
if custom_data_ltx:section_exist("smart_terrains") then
if custom_data_ltx:line_exist("smart_terrains", "none") then
if r_str(custom_data_ltx, "smart_terrains", "none") == "true" then
check = false
end
end
if custom_data_ltx:line_exist("smart_terrains", "respawn_check") then
if r_str(custom_data_ltx, "smart_terrains", "respawn_check") == "false" then
check = false
end
end
end
end
end
return ret_table
end
return nil
end
----------------------------------------------------------------------------------------------------------------------
-- Серверный объект спавнера
----------------------------------------------------------------------------------------------------------------------
class "se_respawn"(cse_alife_smart_zone)
function se_respawn:__init(section) super(section)
self.spawned_obj = {}
-- Таблица для кеширования свойств секций респавна.
self.sectSpawnProps = {}
self.rt_read = false
self.proxy_initialized = false
end
-- сохранение
function se_respawn:STATE_Write(packet)
cse_alife_smart_zone.STATE_Write(self, packet)
local table_size = table.getn(self.spawned_obj)
-- --printf("SPAWNER SAVE table_size[%d]", table_size)
-- print_table(self.spawned_obj)
packet:w_u8(table_size)
for i=1,table_size do
packet:w_u16(self.spawned_obj)
end
utils.w_CTime(packet, self.respawn_time)
if self.respawn_time == nil then
self.respawn_time = game.CTime()
end
--sak.dbglog("%s write respawn_time %s %s", tostring(self:name()), self.respawn_time:dateToString(0), self.respawn_time:timeToString(1))
end
-- восстановление
function se_respawn:STATE_Read(packet, size)
cse_alife_smart_zone.STATE_Read(self, packet, size)
if editor() then
return
end
local table_size = packet:r_u8()
for i=1,table_size do
table.insert(self.spawned_obj, packet:r_u16())
end
if not packet:r_eof() then
self.respawn_time = utils.r_CTime(packet)
self.rt_read = true
--sak.dbglog("%s read respawn_time %s %s", tostring(self:name()), self.respawn_time:dateToString(0), self.respawn_time:timeToString(1))
end
end
-- инициализация объекта.
-- вызывается симулятором.
function se_respawn:on_register()
cse_alife_smart_zone.on_register(self)
----printf("RESPAWN: [%s] se_respawn on_register", tostring(self:name()))
init_respawn_params(self)
end
-- Создаем объект
function se_respawn:create(prob)
if tostring(prob)=="true" then
prob=80
elseif tostring(prob)=="false" then
prob=0
end
if tonumber(prob) == nil then
print_table(self.conditions)
abort("RESPAWN[%s]spawn probability doesn't set", tostring(self:name()))
prob = 0
end
if math.random(100) <= tonumber(prob) then
local spawn_section = ""
local sum = 0
-- Производим рандомную взвешенную выборку
-- с учетом уже заспавленного количества человек.
for k,v in pairs(self.respawn_section) do
--' local tt = self.sectSpawnProps[v.section]
--' local community_rank = tt.community.."_"..tt.rank
--' local s_count = simMaxCount[community_rank]
--' if s_count == nil then
--' s_count = 0
--' end
--' if tt.check == false or
--' self.item_spawn == true or
--' sim_statistic.simNpcCount(tt.community, tt.rank) < s_count
--' then
sum = sum + v.prob
--' end
end
sum = math.random(0, sum)
for k,v in pairs(self.respawn_section) do
--' local tt = self.sectSpawnProps[v.section]
--' local community_rank = tt.community.."_"..tt.rank
--' local s_count = simMaxCount[community_rank]
--' if s_count == nil then
--' s_count = 0
--' end
--' if tt.check == false or
--' self.item_spawn == true or
--' sim_statistic.simNpcCount(tt.community, tt.rank) < s_count
--' then
sum = sum - v.prob
if sum <= 0 then
spawn_section = v.section
break
end
--' end
end
if spawn_section == "" then
-- --printf("SPAWNING [%s], CANT SPAWN, SIMULATION POPULATION EXCEED", tostring(self:name()))
--sak.dbglog("SPAWNING [%s], CANT SPAWN, SIMULATION POPULATION EXCEED", tostring(self:name()))
return false
end
local parent_id = nil
if self.parent ~= nil then
local s_obj = alife():story_object(self.parent)
if s_obj == nil then
abort("SPAWNING [%s], cant find parent with SID [%s]", self:name(), self.parent)
return
end
parent_id = s_obj.id
end
local obj
if parent_id == nil then
obj = alife():create(spawn_section,
self.position,
self.m_level_vertex_id,
self.m_game_vertex_id)
else
obj = alife():create(spawn_section,
self.position,
self.m_level_vertex_id,
self.m_game_vertex_id,
parent_id)
end
amk.on_REspawn(obj,self)
local tt = self.sectSpawnProps[spawn_section]
--sak.dbglog("SPAWNING [%s] -> [%s], CANT SPAWN. NO SMART_TERRAIN AVAILABLE!!!", tostring(self:name()), spawn_section)
-- --printf("SPAWNING [%s] -> [%s], CANT SPAWN. NO SMART_TERRAIN AVAILABLE!!!", tostring(self:name()), spawn_section)
return false
end
end
end
table.insert(self.spawned_obj ,obj.id)
return true
end
end
-- Попытка спаунить объекты. Анализируется сколько уже заспавнено и выбирается один из механизмов - либо
-- мы доспавниваем до минимального количества, либо спавним с заданной вероятностью
function se_respawn:spawn()
-- --printf("RESPAWN: [%s] spawn execute", tostring(self:name()))
--sak.dbglog("RESPAWN: [%s] spawn execute", tostring(self:name()))
if not self.spawn_once then
-- Пробегаемся по списку уже заспавненных объектов и удаляем из них мертвые либо уничтоженные.
for k,v in pairs(self.spawned_obj) do
local obj = level.object_by_id(v)
if obj == nil then
obj = alife():object(v)
end
if obj ~= nil then
if(IsStalker(obj) or IsMonster(obj)) and obj:alive() ~= true then
table.remove(self.spawned_obj, k)
end
else
table.remove(self.spawned_obj, k)
end
end
end
if xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions) == "0" then
-- --printf("SPAWNING [%s], CANT SPAWN. PROBABILITY ZERO!!!", tostring(self:name()))
--sak.dbglog("SPAWNING [%s], CANT SPAWN. PROBABILITY ZERO!!!", tostring(self:name()))
sim_statistic.respawn_enabled(self, false)
return
end
sim_statistic.respawn_enabled(self, true)
if self.spawn_once and not self.already_once_spawned then
self.already_once_spawned = true
end
-- экстренный спаун минимального количества объектов
if table.getn(self.spawned_obj) < self.min_count then
while table.getn(self.spawned_obj) < self.min_count do
--sak.dbglog("RESPAWN: [%s] very small object", tostring(self:name()))
if self:create(100) == false then
return
end
end
return
end
-- делаем несколько попыток заспаунить объект.
for i=1,self.max_spawn do
if self.max_count ~= -1 and table.getn(self.spawned_obj) >= self.max_count then
--sak.dbglog("RESPAWN: [%s] max count reached", tostring(self:name()))
-- --printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(self:name()))
return
end
if self:create(xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions)) == false then
return
end
end
end
--' Удаляем уже заспавненный объект из списка заспавненных
--' Используется только для ящиком со шмотками в смарттеррейнах
function se_respawn:remove_spawned(id)
for k,v in pairs(self.spawned_obj) do
if id == v then
table.remove(self.spawned_obj, k)
end
end
end
-- Обновление респавнера. В зависимости от настроек обновляется либо только в офлайне, либо и там и там.
function se_respawn:execute()
-- --printf("RESPAWN: [%s] se_respawn execute", tostring(self:name()))
if self.already_once_spawned==true then return end
--' Выходим, если у нас установлен событийный спавн.
if self.idle_spawn_min == -1 then
return
end
if self.respawn_time < game.get_game_time() then
-- if not self.proxy_initialized then
-- db.actor_proxy:init()
-- self.proxy_initialized = true
-- end
local idle_time = game.CTime()
local now = game.get_game_time()
--idle_time:setHMSms(0, 0, 0, math.random(self.idle_spawn_min, self.idle_spawn_max)*1000) --посмотрим?
idle_time:setHMSms(math.random(48, 72), 0, 0, math.random(self.idle_spawn_min, self.idle_spawn_max)*1000) -- по моему тут дни получаются?
self.respawn_time = now + idle_time
-- --printf("spawn_count = %s", table.getn(self.spawned_obj))
end
end
-- Обновление в офлайне
function se_respawn:update()
cse_alife_smart_zone.update(self)
if self.respawn_radius == -1 then
sim_statistic.respawn_enabled(self, false)
return
end
if db.actor:position():distance_to(self.position) >= self.respawn_radius then
self:execute()
else
sim_statistic.respawn_enabled(self, false)
end
end
function spawn(name)
local spawner = respawners[name]
if spawner == nil then
return
end
for i=1,spawner.max_spawn do
if spawner.max_count ~= -1 and table.getn(spawner.spawned_obj) >= spawner.max_count then
-- --printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(spawner:name()))
return
end
if spawner:create(xr_logic.pick_section_from_condlist(db.actor_proxy, spawner, spawner.conditions)) == false then
return
end
end
end
function get_respawner_by_parent(parent_id)
return respawners_by_parent[parent_id]
end
-- Сбор статистики
function stats()
local total_spawned = 0
local total_avail = 0
local total = 0
--printf("***************** RESPAWN STATISTIC *********************")
for k,v in pairs(respawners) do
local s = xr_logic.pick_section_from_condlist(db.actor_proxy, v, v.conditions)
local pops = "DISABLE"
if s ~= "nil" and s ~= "0" then
pops = table.getn(v.spawned_obj)
end
local str_pops
if v.max_count == pops then
str_pops = "FULL "..tostring(pops)
else
str_pops = tostring(pops)
end
--printf("[%s] spawns [%s] object", tostring(v:name()), str_pops)
print_table(v.respawn_section)
-- Увеличиваем общие счетчики
total = total + v.max_count
if pops ~= "DISABLE" then
total_avail = total_avail + v.max_count
total_spawned = total_spawned + pops
end
end
--printf("*** SUMMARY ***")
--printf(" total = %s", total)
--printf(" total_avail = %s", total_avail)
--printf(" total_spawned = %s", total_spawned)
--printf("***************")
end
-- Сбор продвинутой статистики статистики по лимитам
function lstats()
local can_spawn = {}
--printf("***************** LIMITS STATISTIC *********************")
for k,v in pairs(respawners) do
-- Запоминаем максимальное количество весов для данного респавнера
local wage = 0
for kk,vv in pairs(v.respawn_section) do
wage = wage + vv.prob
end
-- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить.
for kk,vv in pairs(v.respawn_section) do
local tt = v.sectSpawnProps[vv.section]
local community_rank = tt.community.."_"..tt.rank
if can_spawn[community_rank] == nil then
can_spawn[community_rank] = {community = tt.community, rank = tt.rank}
end
end
end
-- Выводим все это в общей статистике
local total_max, total_prob, total_current, total_limit = 0,0,0,0
for k,v in pairs(can_spawn) do
local cs = sim_statistic.simNpcCount(v.community, v.rank)
local gl = simMaxCount[k]
if gl == nil then gl = 0 end
--printf("%s current=%s limit=%s", k, cs, gl)
end
--printf("TOTAL: current=%s limit=%s", total_current, total_limit)
end
-- Сбор статистики по ненастроенным объектам
function estats()
--printf("***************** SPAWN ERROR STATISTIC *********************")
for k,v in pairs(respawners) do
-- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить.
for kk,vv in pairs(v.respawn_section) do
local tt = v.sectSpawnProps[vv.section]
if tt.community == "nil" or tt.rank == "nil" then
--printf("respawner [%s]", tostring(v:name()))
--printf("Section [%s] community[%s] rank [%s]", vv.section, tt.community, tt.rank)
end
end
end
end
function create_ammo(section, position, lvi, gvi, pid, num)
local ini = system_ini()
local num_in_box = ini:r_u32(section, "box_size")
while num > num_in_box do
alife():create_ammo(section, position, lvi, gvi, pid, num_in_box)
num = num - num_in_box
end
alife():create_ammo(section, position, lvi, gvi, pid, num)
end
local amk_respawner_control={}
local amk_named_respawner_control={}
function init_respawn_params(obj)
amk_respawner_control[obj:name()] = obj
-- Вычитываем настройки спауна
local ini = obj:spawn_ini()
if not ini:section_exist(section_name) then
return
end
obj.respawn_section = r_spawns(ini, section_name, "respawn_section", obj.sectSpawnProps)
if obj.respawn_section == nil then
abort("RESPAWN: [%s] field 'respawn_section' doesn't exist.", obj:name())
end
obj.amk_name = r_str(ini, section_name, "amk_name", nil)
if obj.amk_name then amk_named_respawner_control[obj.amk_name] = obj end
obj.min_count = r_num(ini, section_name, "min_count", 0)
obj.max_count = r_num(ini, section_name, "max_count", -1)
if obj.min_count > obj.max_count and
obj.max_count ~= -1
then
abort("RESPAWN: [%s] min_count > max_count", obj:name())
end
--' FOR DEBUG ONLY, please don't forget to delete
--'if obj.max_count > 0 then
--' obj.min_count = obj.max_count
--'end
obj.max_spawn = r_num(ini, section_name, "max_spawn", 1)
obj.idle_spawn_min, obj.idle_spawn_max = r_2nums(ini, section_name, "idle_spawn")
if obj.idle_spawn_min == nil then
abort("RESPAWN: [%s] field 'idle_spawn' doesn't exist.", obj:name())
end
if obj.idle_spawn_max == nil then
obj.idle_spawn_max = obj.idle_spawn_min
end
--' Вычитка пресетов
if idle_spawn_preset[obj.idle_spawn_min] ~= nil then
obj.idle_spawn_min = idle_spawn_preset[obj.idle_spawn_min]
else
obj.idle_spawn_min = tonumber(obj.idle_spawn_min)
end
if idle_spawn_preset[obj.idle_spawn_max] ~= nil then
obj.idle_spawn_max = idle_spawn_preset[obj.idle_spawn_max]
else
obj.idle_spawn_max = tonumber(obj.idle_spawn_max)
end
obj.str_conditions = r_str(ini, section_name, "conditions", 100)
obj.conditions = xr_logic.parse_condlist(obj, section_name, "conditions", obj.str_conditions)
obj.respawn_radius = r_num(ini, section_name, "respawn_radius", -1)
--' Спешкейс, чтобы сохранить совместимость сейвов.
if obj:name() == "mil_freedom_barier_respawn_1" then
obj.respawn_radius = -1
end
obj.parent = r_num(ini, section_name, "parent", nil)
obj.item_spawn = r_bool(ini, section_name, "item_spawn", false)
-- производим первичную инициализацию
if obj.rt_read == false then
obj.respawn_time = game.CTime()
--sak.dbglog("INIT [%s] %s %s", tostring(obj:name()), obj.respawn_time:dateToString(0), obj.respawn_time:timeToString(1))
end
-- Для сбора статистики сохраняем указатель на респавнер
respawners[obj:name()] = obj
if obj.parent ~= nil then
respawners_by_parent[obj.parent] = obj
end
Если под помощью ты подразумеваешь 'сделай за меня' - то ты ошибся адресом. Тут топик для тех, кто САМ что-то хочет сделать/переделать.
Судя по тому, что поставив заплатку, ты попал на точно такую же фатальную ошибку но в другом скрипте и не утруждаешь себя применить уже полученные сведения ... мое предположение верно. :-(
Сорри, но тратить на эту поделку время не считаю для себя целесообразным.
Попробуй немного напрячь свои познания в скриптах и воспользоваться первой частью рекомендации:
Правильно исправить - подобрать инициализацию/спавн болтов только тогда, когда объект актор уже в игре.
P.S. посмотрев коды болта могу сказать, что срастить с NLC не тривиальная задачка, т.к. в моде (NLC) рюкзак и слоты контролируемы своими скриптами и ... помятуя, что и так немало глюков с рюкзаком-подсумком-разгрузкой, дополнительные сторонние спавны и использование коллбэков только добавят глюков.
MRN$
Ну зачем же так категорично(?):
остаётся только "отдельное задание на каждый предмет"
если уже в цитируемых тобою же словах говорится о возможности внести свои правки/добавки в исходники.
Не так уж и сложно это сделать. Дополнительные поля/параметры давно уже вносятся разными модами в таск-менеджер (тот жен АМК) и неплохо приживаются. Иной вопрос целесообразности: делать штатными средствами, что порой приводит к "почесать правое ухо левой ногой" или же затеять возню с исходными скриптами, что чревато ошибками и битыми сэйвами ... на первых порах.
goust
Смотря но последним постам тут всё просто.
Тебе нужно всего лишь научиться правильно добавлять объекты в игру.=)
"Заплатка" рабочая. Вот потому она и передала ошибку дальше.
А теперь хоть понимай хоть нет. Твоё дело.
В 466-й строке вызывается функция, записанная в С-объекте(движке короче) в поле с ключем "update".
Эта функция "подбирает под себя" (правильнее конечно - индексирует поля. В частности поле 'асtоr') параметры (строка 168) секций подходящих объектов (не знаю как ещё объяснить).
И среди них секции 'асtor' нет.
Р.S.
И как это у вас получается залазить в такую зад...цу?
Научите.=)
отредактировал(а) Gun12: 13-01-2011 01:03 GMT3 час. Не стань номинантом премии Дарвина.
Gun12
Эта как ты вырозился зад...ца,иной раз сама в себя засасывает,Artos ладно буду пробовать,мои познания в скриптах настолько плохи-что там напрягать практически нечего,но я напрягу.
goust
Начни с того, что тебе по силам. Встрой этот "болтовый" мод в исходную игру и ... если получится попробуй более сложное.
В NLC6 строку: 'bolt_mod.net_spawn()' вставляй в самый конец (перед 'return true') 'actor_binder:net_spawn(data)'.
Но ... как уже писал выше, еще немало подводных камешков тебе придется преодолеть ...
Artos
Я на гране нервного срыва,ни чё не получается,нпс все расходятся,ни чё не работает,и вообще мои познания скриптов заканчиваются на добавление какой нибудь функции в bind_stalker,значит не судьба с такими болтами поиграть.
goust
Только что лазил по одному из сайтов, и наткнулся на ответ тебе.
Чтобы не назвали плагиатором цитирую и Пушкина и цитатора :
sabir
Если ты проникнешься смыслом изречения, то сразу увидишь что информации в нем мешок с горсточкой.
... О сколько нам открытий чудных
Готовят просвещенья дух
И опыт, сын ошибок трудных,
И гений, парадоксов друг,
И случай, бог изобретатель...
Прошу обратить внимание на определения: просвещенья дух, опыт и гений - ... а это формула открытий.
Делай выводы.
Ну Бог с ним. Гений не для всех. Но без просвещения и опыта в твоей ситуации делать совсем нечего.
отредактировал(а) Gun12: 13-01-2011 03:03 GMT3 час. Не стань номинантом премии Дарвина.
Тут такой вопрос.
Устанавливал лицензию и поменял некоторые скрипты(правильно),но потом при попытке захода в игру тут вылазиит такая фигня.
Зафиксирована попытка использование эмулироющих программ для запуска приложение.
Вставьте пожалуста лицензионный диск деактивируйти все програмы-эмуляторы и попробуйте запустить приложение.
Вереустанавливал игру всё равно такая же фигня.
Помогите плиз.:-(
добавлено спустя 11 минут
Кто нибуть сталкивался с этип?
добавлено спустя 50 минут
Всё разобрался сам.Пока дождёшься от вас ответа или совета.
отредактировал(а) Propavhiy: 13-01-2011 12:19 GMT3 час.
В task_manager.script есть функция CRandomTask:action_give_task(actor, npc, p1, p2), мне не понятна **5001b67681f3126adde4**]task:load(task_desc.complex_type)[/code]
На АМК форуме написано, что метод load загружает параметры квеста из game_task.xml, а в task_manager.script загружаются квесты их файла task_manager.ltx ...Вообщем впопрос такой:
[code]task:load(что тут надо написать, чтоб квест загрузился из task_manager.ltx?)[/code]
В task_manager.script так сделано, но там код сложноватый и мне не понятно ни чоё.
И вообще, если я делаю квест на скриптах, зачем нужно обязательно квест от куда-то загружать?
999Geka666
Ну раз секции из олспавна можно удалять, а новые точки переходов создавать скриптом, то имхо да.
Интересно, а получается что так можно точку перехода сдвинуть :\
Эта тема закрыта, публикация новых сообщений недоступна.
Продолжая пользоваться сайтом, вы соглашаетесь с использованием файлов cookie. Страницы сайта могут содержать информацию, запрещенную для просмотра посетителям младше 18 лет. Авторское право на серию игр «S.T.A.L.K.E.R» и используемые в ней материалы принадлежит GSC Game World.