- Любое обсуждение нелегального запуска игры, обсуждение noDVD и прочего обхода защиты запуска игры - автор сообщения получит предупреждение + бан аккаунта на 1-7 дней - Перед тем как задать вопрос прочитайте, пожалуйста, FAQ, или воспользуйтесь поиском в теме. Ответы на 98% вопросов по игре уже даны, поверьте, и не раз. - Сообщения содержащие только символы смайлов и типа "+1" будут удаляться сразу, дабы не засорять тему. - За вопрос типа "При переходе в Припять вылетает. Что делать?" выдается предупреждение и бан на трое суток.
- полное описание - faq - прохождение сюжетной линии - полные карты локаций - описание все тайников и как их найти - описание всех предметов - улучшения брони и шлемов + исправлены грамматические ошибки в картах + точно указаны размеры игровых локаций + добавлена карта - "лаборатория х8" в 3D + добавлен монстр - огненный полтергейст + изменены рисунки некоторых монстров + добавлен пункт "Сохранения" + добавлена информация по S.T.A.L.K.E.R. 2
критику только мне в личку (iMMelMan) иногда есть проблемы с открытием дневника - положите в корень диска и/или разблокируйте его
Member
Статус: Не в сети Регистрация: 29.02.2008 Откуда: Москва
VII с патронами вообще отдельная история Наверное все видели что с трупа падает 3-8 патронов (на макс.сложности, штук). Это считается "коробкой", тогда как коробка согласно прописанным в игре правилам (их можно кстати поменять), занимает 30 патронов (если это винтовочные, допустим, патроны, 20 для пистолетных, 10 для дробовых, ну и т.д.-сколько выдает торговец за "щелчок", столько и есть в пачке по дефолту). И обыскав, допустим, 10 трупов, и найдя в каждом по 3 патрона, вы получите 30 патронов, которые занимают - внимание - 10 ячеек из 65535! А не одну. И если эти патроны не продавать, а складывать, то будет пичалька). Так же это хорошо заметно когда продаешь патроны торговцу - ГГ выкладывает их не по 30, а по столько, сколько он поднял с каждого трупа - 7, 5, и т.п.
Для этого дела я включил в игру скрипт перепаковки патронов. Суть его в чем - при поднятии очередных 3 патронов скрипт проверяет, есть ли "неполные" коробки у нас в инвентаре (с числом менее 30). Если такая коробка есть, он добавляет их туда, если "не влезает" - то добавляет сколько влезло, а лишние патроны помечает как новую коробку. Соответственно сколько бы ты патронов не поднял, они автоматом сортируются по пачкам, что позволяет А) сэкономить место в пуле игры Б) продавать проще.
Этот скрипт - сборная солянка из скрипта человека с ником Dunin, он же IG2007, который первый это реализовал, и чужих (в т.ч. моих) корректировок. Я знаю что он какое-то время его сам шлифовал, поэтому может есть версия и лучше моей, однако и моя работает )))
Сам скрипт, помещать в папку scripts со своим именем
Код:
local ammo = {} local inited = false local repack = false
-------- -- инициализация переменных, выполняется единожды -------- function init() local i, result, section, value -- отсюда возьмём размеры полных пачек local sys = system_ini() -- список патронов возьмём из "death_generic.ltx" local ini = ini_file("misc\\death_generic.ltx") local n = ini:line_count("ammo_sections") for i=0,n-1 do result, section, value = ini:r_line("ammo_sections",i,"","") ammo[section] = {} ammo[section].repack = false ammo[section].box = sys:r_u32(section, "box_size") end repack = false inited = true end
-------- -- вызывается при добавлении в инвентарь ГГ любых патрон -- obj - game_object добавляемой пачки -- здесь будем только ставить флажки о необходимости проверки, -- саму проверку и перепаковку сделаем в апдейте актёра, -- если перепаковку делать прям здесь, то будет глюк при загрузки и -- при взятии из нычки кучи патрон (взять всё) -------- function on_take(obj) if not inited then init() end
local section = obj:section() --dbglog("on_take('%s')", section)
if ammo[section].repack == false then if get_ammo_size(obj) < ammo[section].box then ammo[section].repack = true repack = true end end end
-------- -- вызывается из апдейта актёра -- проверяет наличие флажков и вызывает процедуру переупаковки -------- function on_update() if repack then local section, data for section, data in pairs(ammo) do if data.repack then repack_ammo(section, data.box) data.repack = false end end repack = false end end
-------- -- переупаковка патронов заданного типа -- section - строка, имя секции (тип патрон) -- box_size - колличество патрон в полной пачке -- сначало составляем список неполных пачек, затем -- удаляем их и создаём нужное колличество полных -------- function repack_ammo(section, box_size) --dbglog("repack_ammo('%s')", section) local s, t = enum_ammo(section, box_size) if (s > 0) and (table.getn(t) > 1) then --dbglog("repacking(magazins=%d, bullets=%d)", table.getn(t), s) local i, id local sim = alife() local pos = db.actor:position() local lvid = db.actor:level_vertex_id() local gvid = db.actor:game_vertex_id() local pid = db.actor:id()
for i, id in pairs(t) do sim:release(sim:object(id), true) end
while s >= box_size do sim:create_ammo(section, pos, lvid, gvid, pid, box_size) s = s - box_size end
if s > 0 then sim:create_ammo(section, pos, lvid, gvid, pid, s) end end end
-------- -- пробегаемся по инветарю ГГ и собираем инфу о неполных пачках -- section - строка, имя секции (тип патрон) -- box_size - колличество патрон в полной пачке -- возвращает сумарное колличество патрон в неполных пачках и массив id-шников этих пачек -------- function enum_ammo(section, box_size) local i, obj, size local s = 0 local t = {} for i=0, db.actor:object_count()-1 do obj = db.actor:object(i) if obj:section() == section then size = get_ammo_size(obj) if size < box_size then table.insert(t, obj:id()) s = s + size end end end return s, t end
-------- -- возвращает колличество патрон в пачке -- вроде подходящих функций нет, пришлось делать через net_packet -------- function get_ammo_size(obj) local se_obj = alife():object(obj:id()) local packet = net_packet() cse_alife_item_ammo.STATE_Write(se_obj, packet) --packet:r_advance(18) --packet:r_stringZ() --packet:r_advance(8) --packet:r_stringZ() --packet:r_advance(5) packet:r_seek(packet:w_tell() - 2) return packet:r_u16() end
Образец bind_stalker из той же папки, куда импортированы инфопоршены данного скрипта (тут он зовется dunin_ammo). Смотрим по этому имени в теле bind_stalker куда и что вставлено и делаем аналогично
function init (obj) xr_motivator.AddToMotivator(obj) end
function actor_init (npc) npc:bind_object(actor_binder(npc)) end
lasthealth = 0 lasttime = 0 post_process = 0 local weapon_hide = false ---------------------------------------------------------------------------------------------------------------------- class "actor_binder" (object_binder) ---------------------------------------------------------------------------------------------------------------------- function actor_binder:__init (obj) super(obj) self.bCheckStart = false self.weather_manager = level_weathers.WeatherManager() self.actor_detector = xr_detector.actor_detector() end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:net_spawn(data) printf("actor net spawn")
level.show_indicators()
self.bCheckStart = true self.weapon_hide = false -- спрятано или нет оружие при разговоре. weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.
if object_binder.net_spawn(self,data) == false then return false end
db.add_actor(self.object)
if self.st.disable_input_time == nil then level.enable_input() end
return true end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:net_destroy() if(actor_stats.remove_from_ranking~=nil)then actor_stats.remove_from_ranking(self.object:id()) end -- game_stats.shutdown () db.del_actor(self.object)
if sr_psy_antenna.psy_antenna then sr_psy_antenna.psy_antenna:destroy() sr_psy_antenna.psy_antenna = false end
xr_sound.stop_all_sound_object()
object_binder.net_destroy(self) end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:reinit() object_binder.reinit(self)
local npc_id = self.object:id()
db.storage[npc_id] = { }
self.st = db.storage[npc_id] self.st.pstor = nil
self.next_restrictors_update_time = -10000
self.object:set_callback(callback.inventory_info, self.info_callback, self) self.object:set_callback(callback.article_info, self.article_callback, self) self.object:set_callback(callback.on_item_take, self.on_item_take, self) self.object:set_callback(callback.on_item_drop, self.on_item_drop, self) self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self) -- for game stats --self.object:set_callback(callback.actor_sleep, self.sleep_callback, self) self.object:set_callback(callback.task_state, self.task_callback, self) --self.object:set_callback(callback.map_location_added, self.map_location_added_callback, self) self.object:set_callback(callback.level_border_enter, self.level_border_enter, self) self.object:set_callback(callback.level_border_exit, self.level_border_exit, self) self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self) end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:take_item_from_box(box, item) local story_id = box:story_id() if story_id == nil then return end
treasure_manager.take_item_from_box(box, story_id) --[[ local respawner = se_respawn.get_respawner_by_parent(story_id) if respawner == nil then return end
--' Необходимо уменьшить счетчик в респавнере respawner:remove_spawned(item:id())
local smart_terrain = db.strn_by_respawn[respawner:name()] if smart_terrain == nil then return end
local npc = smart_terrain.gulag:get_nearest_online_obj(db.actor:position()) if npc ~= nil then xr_sound.set_sound_play(npc, "reac_box") xr_gulag.setGulagEnemy(smart_terrain:name() , db.actor) end ]] end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:level_border_enter(npc, info_id) self.actor_detector:actor_enter() end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:level_border_exit(npc, info_id) self.actor_detector:actor_exit() end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:info_callback(npc, info_id) printf("*INFO*: npc='%s' id='%s'", npc:name(), info_id) --' Сюжет level_tasks.proceed(self.object) -- Отметки на карте level_tasks.process_info_portion(info_id) end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:on_trade (item, sell_bye, money) if sell_bye == true then game_stats.money_trade_update (money) else game_stats.money_trade_update (-money) end end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:article_callback(npc, group, name) --printf("article_callback [%s][%s]", group, name) if device().precache_frame >1 then return end
if group == "Diary" then news_manager.send_encyclopedy("diary", group) else news_manager.send_encyclopedy("encyclopedy", group) end end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:on_item_take (obj) level_tasks.proceed(self.object) --game_stats.update_take_item (obj, self.object) if obj:clsid() == clsid.wpn_ammo then dunin_ammo.on_take(obj) end end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:on_item_drop (obj) level_tasks.proceed(self.object) --game_stats.update_drop_item (obj, self.object) end ----------------------------------------------------------------------------------------------------------------------
function actor_binder:task_callback(_task, _objective, _state) task_manager.task_callback(_task:get_id(), _objective:get_idx(), _state) if _objective:get_idx() == 0 then if _state == task.fail then news_manager.send_task(db.actor, "fail", _task, _objective) elseif _state == task.completed then task_manager.reward_by_task(_task) news_manager.send_task(db.actor, "complete", _task, _objective) else news_manager.send_task(db.actor, "new", _task, _objective) end else if _task:get_objective(0):get_state() == task.in_progress then news_manager.send_task(db.actor, "update", _task, _objective) end end end
---------------------------------------------------------------------------------------------------------------------- function actor_binder:map_location_added_callback(spot_type_str, object_id) if (false==app_ready()) or (device().precache_frame>1) then return end --'news_manager.send_task(db.actor, "new") end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:update(delta) object_binder.update(self, delta)
--' Проверка потери жизни --[[ if self.object.health - lasthealth > 0.001 or self.object.health - lasthealth < -0.001 then printf("%f | %f", self.object.health, self.object.health - lasthealth, game.time() - lasttime) lasthealth = self.object.health lasttime = game.time() end ]] -- Обновление отключения ввода с клавиатуры. if self.st.disable_input_time ~= nil and game.get_game_time():diffSec(self.st.disable_input_time) >= self.st.disable_input_idle then level.enable_input() self.st.disable_input_time = nil end -- Обновление сна с переносом чувака в указанную позицию if self.st.sleep_relocate_time ~= nil and game.get_game_time():diffSec(self.st.sleep_relocate_time) >= self.st.sleep_relocate_idle then self.object:set_actor_position(self.st.sleep_relocate_point) local dir = self.st.sleep_relocate_point:sub(self.st.sleep_relocate_look) self.object:set_actor_direction(dir:getH()) self.st.sleep_relocate_time = nil end
-- Апдейт прятание оружия игрока во время диалога if weapon_hide == true or self.object:is_talking() then if self.weapon_hide == false then self.object:hide_weapon() self.weapon_hide = true end else if self.weapon_hide == true then self.object:restore_weapon() self.weapon_hide = false end end
-- обновление рестрикторов, которые под логикой, срабатывает через интервалы времени if self.next_restrictors_update_time < time then bind_restrictor.actor_update(delta)
self.next_restrictors_update_time = time + 200
task_manager.actor_update() end
-- обновление постпроцессов if post_process ~= 0 then if post_process:update () == true then post_process = 0 end end
-- обновление пси-антенны if sr_psy_antenna.psy_antenna then sr_psy_antenna.psy_antenna:update(delta) end
--' Вывод сообщения о большой радиации if self.object.radiation >= 0.7 then local hud = get_hud() local custom_static = hud:GetCustomStatic("cs_radiation_danger") if custom_static == nil then hud:AddCustomStatic("cs_radiation_danger", true) hud:GetCustomStatic("cs_radiation_danger"):wnd():SetTextST("st_radiation_danger") end else local hud = get_hud() local custom_static = hud:GetCustomStatic("cs_radiation_danger") if custom_static ~= nil then hud:RemoveCustomStatic("cs_radiation_danger") end end
if self.bCheckStart then printf("SET DEFAULT INFOS")
if not has_alife_info("storyline_actor_start") and (level.name() == "l01_escape") then self.object:give_info_portion("storyline_actor_start") _G.g_start_avi = true printf("*AVI* RUN START AVI") end
-- if not has_alife_info("encyclopedy") then -- self.object:give_info_portion("encyclopedy") -- end
if not has_alife_info("global_dialogs") then self.object:give_info_portion("global_dialogs") end
if not has_alife_info("level_changer_icons") then self.object:give_info_portion("level_changer_icons") end
level_tasks.add_lchanger_location()
self.bCheckStart = false end
-- Обновление упаковщика патронов if not self.object:is_talking() then dunin_ammo.on_update() end end ---------------------------------------------------------------------------------------------------------------------- function actor_binder:save(packet) printf("actor_binder:save(): self.object:name()='%s'", self.object:name()) object_binder.save(self, packet)
--' Сохраняем данные об отключенном вводе if self.st.disable_input_time == nil then packet:w_bool(false) else packer:w_bool(true) utils.w_CTime(packet, self.st.disable_input_time) end
sr_psy_antenna.load(reader) task_manager.load(reader) self.actor_detector:load(reader) end ----------------------------------------------------------------------------------------------------------------------
-- Weapon functions function hide_weapon() weapon_hide = true end function restore_weapon() weapon_hide = false end
// this is test for section iteration /** local function test_section_iteration(file_name, section_name) printf ("file : %s",file_name) printf ("section : %s",section_name)
local file = ini_file(file_name) local n = file:line_count(section_name) printf ("lines : %d",n)
local id, value = "", "", result for i=0,n-1 do result, id, value = file:r_line(section_name,i,"","") printf ("line %d : %s = %s",i,id,value) end end
Advanced member
Статус: Не в сети Регистрация: 27.01.2003 Откуда: Кунгур Фото: 47
Freeman,Doc Перепаковка патронов не всегда полезна: чтобы вынудить НПС выставить на продажу свой ствол (по квестам поиска стволов определнного типа дешевле и проще купить их ,чем искать или чинить), надо продать ему другой ствол в любом состоянии, на который он польстится, плюс патроны к нему, если ствол у НПС в данный момент под другой патрон. Вот тут-то и заметна разница, продать 1 патрон или 30... Отматывается он элементарно: скидываем в окне обмена пачки, пока не дойдем до уполовиненной, затем отматываем обратно целые.
Никто не подскажет есть ли для Припяти набор исправлений без кардинального изменения геймплея и добавления новых локаций, кучи квестов, транспорта и прочей мути ? Что-то наподобие OGSM для Теней и Неба, желательно совместимый с графическими модами типа AtmosFear и SWTC. Или сборка может какая есть с фиксами и графоном ?
Advanced member
Статус: Не в сети Регистрация: 27.01.2003 Откуда: Кунгур Фото: 47
АМ3 По-первости очень помогает дробить обрезом пачку и продавать как 10 - в начале денег не то чтобы нет - их совсем нет. Ну а потом уже не актуально, да.
Member
Статус: Не в сети Регистрация: 06.04.2011 Фото: 3
Ребята, а как можно инструменты для калибровки получить на Затоне? Понятно, что сами они там не появятся и в некотором роде это будет читерство, но все же начиная в N-ый раз игру, в этот раз хотелось бы дичь поотстреливать (сюжетная линия в данный момент не интересует), да ружья на апгрейде разные проверить, а инструменты в Припяти - пока до них доберешься, игра уже будет по сути дела пройдена.
Member
Статус: Не в сети Регистрация: 01.08.2004 Откуда: Одесса Фото: 4
Faitzz
Если играете оригинальную (1.6.02) версию игры, то можно вот так:
- вытащите из архива игры (..\resources\resources.dbN) файл 'ui_main_menu.script'; - найдите в нём строки: if dik == DIK_keys.DIK_Q then self:OnMessageQuitWin() - добавьте после них: elseif db.actor~=nil and dik==DIK_keys.DIK_F2 then alife():create("toolkit_3",db.actor:position(),db.actor:level_vertex_id(),db.actor:game_vertex_id(),db.actor:id()) - сохраните изменённый файл; - создайте в верхнем каталоге STALKER-a (там, где каталог 'bin') цепочку каталогов: \gamedata\scripts - в последний (\scripts) поместите поправленный файл 'ui_main_menu.script'; - запустите игру и загрузите сохранение; - нажмите последовательность клавиш: <ESC>--<F2>--<ESC> - зайдите в инвентарь: там появится набор "Инструменты для калибровки".
Если правка представляет какую-то сложность, то "поправленный" 'ui_main_menu.script' можно взять вот по этой ссылке (сёрвер глючит, поэтому лучше копировать и вставлять руками): только в этом случае жесткая привязка к версии (1.6.02) игры.
Member
Статус: Не в сети Регистрация: 06.04.2011 Фото: 3
Oldster, благодарю. Интересное решение. А не встречались ли вам моды, где инструменты убирались из Припяти и располагались где-нибудь на Затоне или Юпитере?
Advanced member
Статус: Не в сети Регистрация: 05.03.2003 Откуда: Россия,Поволжье
Faitzz писал(а):
моды, где инструменты убирались из Припяти и располагались где-нибудь на Затоне или Юпитере?
В какой-то из версий SGM инструменты появлялись в случайном порядке, так что при удаче полный набор можно было получить сразу после первого перехода на Янов. В Misery 2 иструменты как раз разбросаны на двух первых локациях, на каждой по 6 случайных точек появления.
_________________ С каждым днём всё радостнее жить.
Member
Статус: Не в сети Регистрация: 01.08.2004 Откуда: Одесса Фото: 4
Faitzz Попадалось (как уже писал kv0) в SGM. Если посмотреть конфигурации апгрейдов оружия, то в них столько чуши, которая даже с натяжкой не то, что на 'реальную', даже на 'игровую' не тянет. Мне больше нравиться подход, используемый в SoC: параметры оружия прописываются максимально приближено к оригинальным (благо движок игры отрабатывает их довольно точно), а 'вкусности' формируются дополнительными (но вполне реальными) обвесами в системе уникальных предметов, которые выдаются\появляются как призовые.
Цитата:
... да ружья на апгрейде разные проверить
Мне кажется, что от сравнения апгрейдов, скорей всего получите эффект Skyrim-a: после выстрела на тебя падает с неба здоровая хреновина, размером с приличную маршрутку с крылышками, подойдя к которой и увидев ту занозу (стрелу), которая её завалила - становится смешно. Но это фэнтези, а STALKER, как ни крути, всё-же 'Сталкер'.
Member
Статус: Не в сети Регистрация: 06.04.2011 Фото: 3
Oldster, мне больше нравится мысль, что было бы хорошо применить несколько апгрейдов (без противоречия друг к другу), 5-7 всего, но запчасти для этих апгрейдов нужны уникальные и искать их надо по всем локациям в самых неожиданных местах. А инструменты нужно убрать вообще.
Member
Статус: Не в сети Регистрация: 31.03.2011 Откуда: Омск
Игровой баланс всё-же великая вещь. Недавно начал sgm и получил почти в начале все три комплекта для техника. Заточил "рысь" да ещё поднял тактику боя для неё и "альфа" стала просто целью. Интерес к игре быстро упал. Хотя видимо мне очень "повезло"
Advanced member
Статус: Не в сети Регистрация: 05.03.2003 Откуда: Россия,Поволжье
Faitzz писал(а):
применить несколько апгрейдов (без противоречия друг к другу), 5-7 всего, но запчасти для этих апгрейдов нужны уникальные и искать их надо по всем локациям в самых неожиданных местах. А инструменты нужно убрать вообще
Не знаю, мне кажется оптимальнее, когда можно кастомизировать оружие по своему усмотрению из отдельных съёмных элементов: разных видов прикладов, рукояток, прицелов, ПБС и т.д. Подобный подход уже просматривается в новом разрабатываемом моде от Шокера:
Видео разработки
_________________ С каждым днём всё радостнее жить.
Member
Статус: Не в сети Регистрация: 01.08.2004 Откуда: Одесса Фото: 4
labor37 писал(а):
Игровой баланс всё-же великая вещь.
По-моему это и есть основная проблема выходящих в последнее время большинства модов. Сами по себе модостроители - в общем-то яркие, самобытные, иногда даже личности. И это главное препятствие: в результате сведения их наработок в одном моде, получается не цельный продукт, а нечто, даже на лоскутное одеяло не похожее. Напоминает старую репризу Райкина: "Кто сшил костюм?" - компоненты мода вроде сбиты качественно, а игры нет и в помине.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 33
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения