iDreD 5 Опубликовано 12 Января 2011 Поделиться Опубликовано 12 Января 2011 (изменено) Подскажите пожалуйста - как телепортировать НПС на нужную мне позицию? Юзал вот такую функцию: --Телепортируем указанного НПС к нужной нам позиции function select_lion_pos() for a=10,65635,1 do local obj=alife():object(a) if obj and string.find(obj:name(),"podval_lion") then alife():set_npc_position(vector():set(269.129,20.55,300.204),8176,0) end end end Но НПС не телепортируется. // Почти все ф-ии игры содержаться в lua_help.script, если что-то нужно - ищите их там, только не надо их выдумывать. Министр. Изменено 12 Января 2011 пользователем Министр Работа в Sculptris 3D [туториал] Страничка на Проза.ру Ссылка на комментарий
Stalk15 27 Опубликовано 12 Января 2011 Поделиться Опубликовано 12 Января 2011 (изменено) ФеНиКс Отслеживай использование одного из 6 твоих предметов и подсчитывай кол-во использований. Я вот тут говорил, как сделать типа запрет на юз итема. Если не знаешь, как отследить юз одного из 6 итемов, читани это: Erlik: добавляем bind_stalker в метод actor_binder:reinit() еще один каллбек Код self.object:set_callback(callback.use_object, OnUseObject, self) OnUseObject это имя функции которая будет вызываться, когда эктор будет использовать предметы типа хлеба\водки\антирада\аптечки\бинта\дринка и т.д. - то есть те которые имеют менюшку "использовать". Для того, чтобы использование предмета можно было отследить, в конфиге у него должен быть указан класс от одного из вышеуказанных итемсов. И далее радуемся жизни с этой функцией: Код function OnUseObject(obj, who) if obj then if obj:section() =="предмет" then -- здесь делаем проверку на секцию нужного предмета действие end end end можно добавить данную функцию в виде метода в bind_stalker сделав так: function actor_binder:OnUseObject(obj, who) сюда ставим проверки end тогда каллбек нужно прописать так self.object:set_callback(callback.use_object, self.OnUseObject, self) PS: дроп предмета - то есть его выкидывание - данный коллбек не отслеживает. Кстати каллбек можно и не вписывать в bind_stalker, а установить его на эктора в теле своей функции в своем файле(биндере) - что я и сделал. Изменено 12 Января 2011 пользователем Stalk15 Ссылка на комментарий
IQDDD 5 Опубликовано 12 Января 2011 Поделиться Опубликовано 12 Января 2011 а чтобы сохранить данные при загрузке игры, используй нет пакет. Ссылка на комментарий
goust 1 Опубликовано 14 Января 2011 Поделиться Опубликовано 14 Января 2011 (изменено) Не могу совместить 2 скрипта -- биндер болтов drop_bolt={} function init(obj) local bag = BBolt(obj) obj:bind_object(bag) end class "BBolt" (object_binder) function BBolt:__init(obj) super(obj) self.object=obj end function BBolt:reload(section) object_binder.reload(self, section) end function BBolt:reinit() object_binder.reinit(self) end function BBolt:update(delta) object_binder.update(self, delta) end function OnSpawnFBolt(arg, iId, gObj) local parent=alife():object(iId).parent_id or 65535 if parent==65535 then local h = hit() h.draftsman = db.actor h.type = hit.strike h.direction = vector():set(1,0,0) h.power = 1 h.impulse = 1 gObj:hit(h) end end 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 function BBolt:net_destroy() --dbg.log("биндер болт---нет дестрой") if drop_bolt[self.object:id()] then local sobj=alife():create("fake_bolt", self.object:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id()) level.client_spawn_manager():add(sobj.id, 0, OnSpawnFBolt, 0) drop_bolt[self.object:id()]=nil end object_binder.net_destroy(self) end function BBolt:net_save_relevant() return true end и --[[------------------------------------------------------------------------------------------------------------------ Respawner. Схема обновления популяции всего всего всего в симуляции. by Stohe(Диденко Руслан) --------------------------------------------------------------------------------------------------------------------]] --function printf() --end local section_name = "respawn" local i,k,v = 0,0,0 -- Таблица ограничений на спаун: всего в симуляции не должно быть больше, чем указано. local simMaxCount = { stalker_novice = 26, stalker_regular = 24, stalker_veteran = 22, stalker_master = 10, monolith_novice = 20, monolith_regular = 15, monolith_veteran = 17, monolith_master = 15, military_novice = 20, military_regular = 16, military_veteran = 22, military_master = 20, killer_novice = 20, killer_regular = 15, killer_veteran = 15, killer_master = 20, ecolog_novice = 15, ecolog_regular = 20, ecolog_veteran = 20, ecolog_master = 10, dolg_novice = 20, dolg_regular = 17, dolg_veteran = 18, dolg_master = 8, freedom_novice = 25, freedom_regular = 10, freedom_veteran = 13, freedom_master = 10, bandit_novice = 15, bandit_regular = 20, bandit_veteran = 19, bandit_master = 15, zombied_novice = 10, zombied_regular = 7, zombied_veteran = 5, zombied_master = 5, sniper_novice = 20, sniper_regular = 17, sniper_veteran = 15, sniper_master = 15, green_novice = 15, green_regular = 25, green_veteran = 25, green_master = 15, rat_weak = 300, rat_normal = 300, rat_strong = 300, tushkano_weak = 300,tushkano_normal = 300, flesh_weak = 48, flesh_normal = 116, flesh_strong = 82, boar_weak = 144, boar_normal = 116, boar_strong = 94, dog_weak = 166, dog_normal = 232, dog_strong = 312, pseudodog_weak = 59, pseudodog_normal = 80, pseudodog_strong = 60, psy_dog_weak = 15, psy_dog_normal = 15, psy_dog_strong = 15, zombie_weak = 61, zombie_normal = 50, zombie_strong = 35, snork_weak = 100, snork_normal = 61, snork_strong = 15, poltergeist_weak = 30,m_poltergeist_normal_tele = 20,m_poltergeist_normal_flame = 10, pseudo_gigant_weak = 43, controller_weak = 36, burer_weak = 40, bloodsucker_weak = 14, bloodsucker_normal = 80, bloodsucker_strong = 30 } 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 sectSpawnProps[spawn.section] = {community = community, rank = rank, check = check} 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 -- --printf("SPAWNER READ table_size[%d]", table_size) -- print_table(self.spawned_obj) 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] -- --printf("SPAWN [%s] -> [%s]", tostring(self:name()), obj:name()) --sak.dbglog("SPAWN [%s] -> [%s]", tostring(self:name()), obj:name()) if self.item_spawn == false then if tt.check == true and not self.amk_name then obj:brain():update() local smart_terrain_id = obj:smart_terrain_id() --sak.dbglog("SPAWN [%s] move_offline [%s], interactive [%s], smart_terrain_id [%s]", tostring(self:name()), tostring(self:move_offline()), tostring(self:interactive()), smart_terrain_id) ----printf("SPAWN [%s] move_offline [%s], interactive [%s], smart_terrain_id [%s]", tostring(self:name()), tostring(self:move_offline()), tostring(self:interactive()), smart_terrain_id) if smart_terrain_id ~= 65535 then table.insert(self.spawned_obj ,obj.id) local pos = obj.position -- --printf("SPAWNING [%s] -> [%s], position [%s][%s][%s]", tostring(self:name()), spawn_section, pos.x, pos.y, pos.z) local sm_obj = alife():object(smart_terrain_id) -- --printf("SPAWNING for SMART [%s] : [%s] -> [%s]", self:name(), obj:name(), sm_obj:name()) --sak.dbglog("SPAWNING for SMART [%s] : [%s] -> [%s]", self:name(), obj:name(), sm_obj:name()) return true else alife():release(obj, true) --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 --sak.dbglog("RESPAWN: [%s] se_respawn execute %s %s", tostring(self:name()), now:dateToString(0), now:timeToString(1)) --sak.dbglog("next respawn %s %s", self.respawn_time:dateToString(0), self.respawn_time:timeToString(1)) -- Производим попытку заспаунить объекты self:spawn() -- --printf("spawn_count = %s", table.getn(self.spawned_obj)) end end -- Обновление в офлайне function se_respawn:update() cse_alife_smart_zone.update(self) --'--printf("RESPAWN: [%s] se_respawn update_offline", tostring(self:name())) self:execute() end -- Обновление в онлайне function se_respawn:update_online() --'cse_alife_smart_zone.update(self) --'--printf("RESPAWN: [%s] se_respawn update_online", tostring(self:name())) if self.respawn_radius == -1 then sim_statistic.respawn_enabled(self, false) return end if db.actor and self.object:position():distance_to(db.actor: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 --sak.dbglog("spawn("..tostring(spawner:name())..")") 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 total_current = total_current + cs total_limit = total_limit + gl --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.spawned_goes_online = r_bool(ini, section_name, "spawned_goes_online", nil) obj.spawn_once = r_bool(ini, section_name, "spawn_once", false) 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 --sak.dbglog("spawn_min %d spawn_max %d", obj.idle_spawn_min, obj.idle_spawn_max) 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 --' Отметка респавнера мапспотом(для статистики) sim_statistic.register_respawn(obj) end function reinit_spawner_params(name) if amk_respawner_control[name] then init_respawn_params(amk_respawner_control[name]) end end function get_respawner_by_name(name) if amk_named_respawner_control[name] then return alife():object(amk_named_respawner_control[name].id) end end происходит вылет: Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp Line : 73 Description : <no expression> Arguments : LUA error: ...r.-Тени Чернобыля\gamedata\scripts\se_respawn.script:466: attempt to index field 'actor' (a nil value) Как это исправить? // Исправляется правильным совмещением. Ничем другим помочь не могу. Министр. Изменено 14 Января 2011 пользователем Министр VODKA connected people... Ссылка на комментарий
Якут 0 Опубликовано 15 Января 2011 Поделиться Опубликовано 15 Января 2011 (изменено) Товарищи сталкеры, как сделать в ЗП чтобы при проверки предмета в инвентаре актера происходил спавн НПС. Вот функции по отдельности проверка function proverka_pda_tryp() if db.actor:object("pda_tryp") then return true end return false end спавн function spawn_zasada_merc() alife():create("merc_zasada_01", vector():set(57.167991638184, 10.893405914307, 367.46084594727), 1059286, 137) alife():create("merc_zasada_02", vector():set(53.669364929199,12.433765411377,375.51013183594), 1053811, 137) alife():create("merc_zasada_03", vector():set(54.97501373291,11.896924972534,356.54852294922), 1056593, 138) end а как их совместить не знаю.Сорри если вопрос глупый :ny_ph34r_1: Изменено 15 Января 2011 пользователем Якут Ссылка на комментарий
Painter 3 412 Опубликовано 15 Января 2011 Поделиться Опубликовано 15 Января 2011 (изменено) Создай скрипт (например test_proverka) и введи туда эту функцию: function proverka_pda_tryp() if db.actor:object("pda_tryp") then test_spawn.spawn_zasada_merc() end end Теперь создай новый скрипт (например test_spawn) и введи это: function spawn_zasada_merc() alife():create("merc_zasada_01", vector():set(57.167991638184, 10.893405914307, 367.46084594727), 1059286, 137) alife():create("merc_zasada_02", vector():set(53.669364929199,12.433765411377,375.51013183594), 1053811, 137) alife():create("merc_zasada_03", vector():set(54.97501373291,11.896924972534,356.54852294922), 1056593, 138) end Осталось самое главное - открой bind_stalker.script, найди строчку: xr_sound.update(self.object:id()) И добавь после неё это: test_proverka.proverka_pda_tryp() Изменено 26 Ноября 2019 пользователем Jurok Портфолио Ссылка на комментарий
Garry_Galler 7 Опубликовано 15 Января 2011 Поделиться Опубликовано 15 Января 2011 (изменено) Всё. Теперь сохраняй и заходи в игру И будет его ждать армия клонов merc_zasada_01 - (каждую секунду по сотне) - как только он возьмет нужный ПДА Уж не апдейт, а на take нужно ставить: найти в bind_stalker этот код function actor_binder:on_item_take (obj) level_tasks.proceed(self.object) --game_stats.update_take_item (obj, self.object) --******************************************* и сюда вписать вызов test_proverka.proverka_pda_tryp() --******************************************* end или даже так лучше - вписать вот это: if obj and obj:section()=="pda_tryp" then имя_файла.spawn_zasada_merc() end А еще не помешает добавить проверку на инфопоршень перед спавном NPC - а после спавна инфопоршень выдать. А то NPC будут спавниться каждый раз когда данный пда будет в инвентарь браться. Изменено 15 Января 2011 пользователем Garry_Galler Ссылка на комментарий
Painter 3 412 Опубликовано 15 Января 2011 Поделиться Опубликовано 15 Января 2011 Garry_Galler, можно сделать так: function proverka_pda_tryp() if not has_alife_info("твой_инфопоршень") and db.actor:object("pda_tryp") then test_spawn.spawn_zasada_merc() db.actor:give_info_portion("твой_инфопоршень") end end И никакой "армии клонов" не будет. Портфолио Ссылка на комментарий
ФеНиКс 2 Опубликовано 15 Января 2011 Поделиться Опубликовано 15 Января 2011 self.object:set_callback(callback.inventory_info, self.info_callback, self) Что значит выделенная строка? Подчеркнутое я знаю это имя функции. Ссылка на комментарий
Garry_Galler 7 Опубликовано 15 Января 2011 Поделиться Опубликовано 15 Января 2011 (изменено) Jurok Разумеется можно - но зачем апдейтить то? Можно ведь обойтись и более подходящим для данного случая методом эктор биндера. ФеНиКс Это одно из перечислений класса callback - полный список можешь найти в lua help. callback.inventory_info срабатывает на открытие инвентарных окон. Изменено 15 Января 2011 пользователем Garry_Galler Ссылка на комментарий
ФеНиКс 2 Опубликовано 15 Января 2011 Поделиться Опубликовано 15 Января 2011 (изменено) С этим Понятно, теперь надо разобраться с этим... В биндере прописал ко всем колбэкам: self.object:set_callback(callback.use_object, self.stepen_prozorlivosti, self) в отдельном файле: function actor_binder:stepen_prozorlivosti(obj, who) ogranichtel_zrachki.useobject(obj) end в файле: ogranichtel_zrachki local CntUseItem function useobject(obj) local Item= {baton_b,conserva,vodka} if obj then if Item[obj:section()] then CntUseItem = CntUseItem +1 if CntUseItem == 3 then db.actor:give_info_portion("z1") this.Timer_prof_32() db.actor:drop_item(obj) local tmpo = this.spawn_vs(obj:section()) news_manager.send_tip(db.actor,"Вы сыты",nil,nil,10000) db.actor:transfer_item(obj,db.actor) alife():release(tmpo) end end end end local ono = false local Timer_prof function Timer_prof_32() --/ запуск таймера if not ono then Timer_prof = time_global() + 1*70000 ono = true end if ono and not Timer_prof then ono = false end end function Timer_prof_4() --/ вызывается из ':update' сталкер-биндера if Timer_prof and Timer_prof < time_global() then --/ проверка текущего значения Timer_prof = nil --/ выключаем таймер db.actor:disable_info_portion("z1") end end function spawn_vs(spawn_item,npc) if npc==nil then npc=db.actor end return alife():create(spawn_item, npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()) end Функция просто не работает... таймер само собой стоит на бинде, но до таймера дело не доходит... сообщение не выдается. Изменено 15 Января 2011 пользователем ФеНиКс Ссылка на комментарий
Garry_Galler 7 Опубликовано 15 Января 2011 Поделиться Опубликовано 15 Января 2011 (изменено) ФеНиКс Со всем кодом не разбирался - но сразу в глаза бросается ошибка: local Item= {baton_b,conserva,vodka} правильно так local Item= {baton_b = true,conserva=true,vodka=true} иначе у тебя в таблице вместо предметов - одни nil. Ты делаешь проверку по ключу - но в твоем же варианте - ключи не строки, а цифры(таблицы lua по умолчанию индексируются цифрам - 1,2,3 и т.д). То есть у тебя получается: {[1]=baton_b,[2]=conserva, [3]=vodka} - при этом значения ключей равны nil. А нужно чтобы ключами были строки соответствующие названиям предметов по секции. Изменено 15 Января 2011 пользователем Garry_Galler Ссылка на комментарий
Stalk15 27 Опубликовано 16 Января 2011 Поделиться Опубликовано 16 Января 2011 ФеНиКс Еще не понятно, зачем ты функцию actor_binder:stepen_prozorlivosti(obj, who) пишешь в отдельном файле. Нужно в бинд_сталкере писать. Ссылка на комментарий
Disord 1 Опубликовано 16 Января 2011 Поделиться Опубликовано 16 Января 2011 (изменено) Подскажите, пожалуйста, где можно прочитать информацию о смарттеррейнах? Что это такое и с чем это едят. На вики смотрел - там только способ заспавнить смарттеррейны, поиск тоже юзал. Изменено 16 Января 2011 пользователем Disord Ссылка на комментарий
ФеНиКс 2 Опубликовано 16 Января 2011 Поделиться Опубликовано 16 Января 2011 (изменено) Как прописать большому кол-ву НПС одну и ту же логику я пытался просто прописать одну и туже, но получаю вылет. Логика снайпера(т.е. нужно чтобы все НПСам присваивалась логика: [logic] active = raketa [raketa] sniper = true Вылет вот такой: Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : <no expression> Arguments : LUA error: ....r. - shadow of chernobyl\gamedata\scripts\_g.script:20: bad argument #2 to 'format' (string expected, got no value) Это если прописать в кастом дату всем одну логику. Изменено 16 Января 2011 пользователем ФеНиКс Ссылка на комментарий
Lexa23 0 Опубликовано 16 Января 2011 Поделиться Опубликовано 16 Января 2011 Помогите. Я создал НПС как заставить его чтобы он патрулировал местность? Ссылка на комментарий
AKKK1 6 Опубликовано 16 Января 2011 Поделиться Опубликовано 16 Января 2011 Если нпс в гулаге то все просто t = { section = "logic@esc_lager_kamp1",для любой работы логика [logic@esc_lager_kamp1] active = kamp1@esc_lager [kamp1@esc_lager] center_point = camp_center path_walk = camp_center_task soundgroup = esc_lager meet = meet@lager если нет то по анологично Ссылка на комментарий
gruber 2 481 Опубликовано 16 Января 2011 Поделиться Опубликовано 16 Января 2011 ФеНиКс, Прямо так и написал как в примере? Lexa23, Прочитать какой нибудь тутор по логике и сделать нпс логику патруль Ссылка на комментарий
TRAMP14 1 Опубликовано 16 Января 2011 Поделиться Опубликовано 16 Января 2011 Как через скрипт (в игре) можно прибавлять и убавлять максимальный переносимый вес? Ссылка на комментарий
ФеНиКс 2 Опубликовано 16 Января 2011 Поделиться Опубликовано 16 Января 2011 gruber Естественно всё так и есть. Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти