• Страница 1 из 1
  • 1
Архив - только для чтения
Форум » Архив » Устаревшие темы » Магазинное питание оружия (Попробуем разобраться, как адаптировать под различные моды)
Магазинное питание оружия
Российская Федерация  Mirage
Воскресенье, 03.02.2013, 13:13 | Сообщение # 1
Независимый аниматор
Статус:
Бывалый:
Сообщений: 1130
Награды: 2
Регистрация: 09.06.2012

Только для версии 1.0006, у 1.0004 xr_motivator по другому адаптируется.
Многие игроки знают, что существует такая модификация от товарища Kirag, но не умеют адаптировать под свои любимые моды. В этой статье, попробуем разобраться, что да как.
Итак, самое трудное при адаптации этого мода-это адаптация скриптов. С них и начнем.
Адаптация скриптов.
Сначала попробуем адаптировать _g.script.
Открываем ее через блокнот и после строчек

Код
function dbglog(fmt,...)
       local msg = string.format(fmt, ...)
       local msg_no_ws = string.gsub(msg, "%s", "_")
       get_console():execute("dbg:" .. msg_no_ws)
end


добавляем вот такие строчки:
Код

function qqq(n,o)
       local scr = true
       local con = true
       if o then
        if o == 1 or o == 0 then
         scr = false
        end
        if o == 2 or o == 0 then
         con = false
        end
       end
       local k = "debug data QQQ "..tostring(n)
       if scr then
        if db.actor then
         news_manager.send_tip(db.actor, k, nil, nil, 5000)       
        end
       end
       if con then
        get_console():execute    ("load "..k)       
        get_console():execute    ("flush")       
       end
end

function qqqv(v,n,o)
       local scr = true
       local con = true
       if type(v) == "string" then
        v_name = v
       else
        o = n
        n = v
        v_name = "vector"
       end
       if o then
        if o == 1 or o == 0 then
         scr = false
        end
        if o == 2 or o == 0 then
         con = false
        end
       end
       local v_comp = ": nil"
       if n ~= nil then
        v_comp = ": x = "..n.x..", y = "..n.y..", z = "..n.z
       end
       local k = "debug data QQQ "..v_name..v_comp
       if scr then
        if db.actor then
         news_manager.send_tip(db.actor, k, nil, nil, 5000)       
        end
       end
       if con then
        get_console():execute    ("load "..k)       
        get_console():execute    ("flush")       
       end
end

function parse_data(str)
       local string_parts = {}
       if str == nil then
        string_parts[1] = nil
        return string_parts
       end
       local str_beg,str_end
       str_end = str
       local split_pos = find_split_pos(str_end)
       while split_pos ~= nil do
        str_beg, str_end = split_string(str_end,split_pos)
        table.insert(string_parts,str_beg)
        split_pos = find_split_pos(str_end)
       end
       table.insert(string_parts,str_end)
       return string_parts
end

function find_split_pos(str)
       local split_pos = string.find(str,",")
       if split_pos == nil then
        return nil
       end
       local br1_pos = string.find(str,"(",1,true)
       local br2_pos = string.find(str,")",1,true)
       if br1_pos ~= nil and br2_pos ~= nil and br1_pos < br2_pos and split_pos > br1_pos then
        local str_end1 = string.sub(str,(br2_pos +1),string.len(str))
        if string.find(str_end1,",") ~= nil then
         split_pos = br2_pos + string.find(str_end1,",")
        else
         split_pos = nil
        end
       end
       return split_pos
end

function split_string(str,split_pos)
       local str_beg = (string.sub(str,1,split_pos-1))
       local str_end = string.sub(str,(split_pos+1),string.len(str))
       return str_beg,str_end
end


Внимание, у каждой модификации _g.script отличаются. Если такой строчки нет, то добавляйте это перед строкой
Код
----------------------------------------------------------------------
if nil == time_global then
       time_global = function () return device():time_global() end
end


Скрип наполовину готов. Находим в самом конце вот такие строчки:
Код
ammo_section = {}
ammo_section["ammo_9x18_fmj"]  = true
ammo_section["ammo_9x18_pbp"]  = true
ammo_section["ammo_9x18_pmm"]  = true
ammo_section["ammo_9x19_fmj"]  = true
ammo_section["ammo_9x19_pbp"]  = true
ammo_section["ammo_5.45x39_fmj"]    = true
ammo_section["ammo_5.45x39_ap"]  = true
ammo_section["ammo_5.56x45_ss190"]    = true
ammo_section["ammo_5.56x45_ap"]  = true
ammo_section["ammo_5.7x28_fmj"]  = true
ammo_section["ammo_5.7x28_ap"]  = true
ammo_section["ammo_7.62x54_7h1"]    = true
ammo_section["ammo_7.62x54_ap"]  = true
ammo_section["ammo_7.62x54_7h14"]    = true
ammo_section["ammo_9x39_pab9"]  = true
ammo_section["ammo_gauss"]   = true
ammo_section["ammo_9x39_ap"]  = true
ammo_section["ammo_9x39_sp5"]  = true
ammo_section["ammo_11.43x23_fmj"]    = true
ammo_section["ammo_11.43x23_hydro"]    = true
ammo_section["ammo_12x70_buck"]  = true
ammo_section["ammo_12x76_dart"]  = true
ammo_section["ammo_12x76_zhekan"]    = true

Удаляем все эти строки, так как там не все патроны и вставим вот это:
Код
ammo_section = {}
ammo_section["ammo_9x18_fmj"]  = true
ammo_section["ammo_9x18_pbp"]  = true
ammo_section["ammo_9x18_pmm"]  = true
ammo_section["ammo_9x19_fmj"]  = true
ammo_section["ammo_9x19_pbp"]  = true
ammo_section["ammo_5.45x39_fmj"]    = true
ammo_section["ammo_5.45x39_ap"]  = true
ammo_section["ammo_5.56x45_ss190"]    = true
ammo_section["ammo_5.56x45_ap"]  = true
ammo_section["ammo_5.7x28_fmj"]  = true
ammo_section["ammo_5.7x28_ap"]  = true
ammo_section["ammo_7.62x54_7h1"]    = true
ammo_section["ammo_7.62x54_ap"]  = true
ammo_section["ammo_7.62x54_7h14"]    = true
ammo_section["ammo_9x39_pab9"]  = true
ammo_section["ammo_gauss"]   = true
ammo_section["ammo_9x39_ap"]  = true
ammo_section["ammo_9x39_sp5"]  = true
ammo_section["ammo_11.43x23_fmj"]    = true
ammo_section["ammo_11.43x23_hydro"]    = true
ammo_section["ammo_12x70_buck"]  = true
ammo_section["ammo_12x76_dart"]  = true
ammo_section["ammo_12x76_zhekan"]    = true
ammo_section["ammo_357_jfp"]  = true
ammo_section["ammo_357_jhp"]  = true
ammo_section["ammo_7.62x25_p"]  = true
ammo_section["ammo_7.62x25_ps"]  = true
ammo_section["ammo_7.62x39_fmj"]    = true
ammo_section["ammo_7.62x39_ap"]  = true
ammo_section["ammo_7.62x51_fmj"]    = true
ammo_section["ammo_7.62x51_ap"]  = true
ammo_section["ammo_7.92x57_fmj"]    = true
ammo_section["ammo_7.92x57_ap"]  = true
ammo_section["ammo_bolt"]   = true
ammo_section["ammo_gauss_std"]  = true
ammo_section["ammo_gauss_ndl"]  = true
ammo_section["ammo_samopal"]  = true


Все, скрипт готов.

А теперь перейдем к скрипту bind_stalker.script. Тут уже сложнее.
Открываем скрипт.
В функции
----------------------------------------------------------------------------------------------------------------------
function actor_binder:net_spawn(data)
после строк
if(actor_stats.add_to_ranking~=nil)then
actor_stats.add_to_ranking(self.object:id())
end
добавляем вот эти строки:
Код
if xr_logic.pstor_retrieve(db.actor, "first_run", 0)==0 then       
        -- доп. учет веса
        if not db.actor:object("dark_matter_container1") then
         spawn.inv("dark_matter_container1")
        end
        if not db.actor:object("dark_matter_container2") then
         spawn.inv("dark_matter_container2")
        end
              
        xr_logic.pstor_store(db.actor, "first_run", 1)
              end


Так, идем дальше.

В функции
----------------------------------------------------------------------------------------------------------------------
function actor_binder:net_destroy()
После строки
self.object:set_callback(callback.take_item_from_box, nil)
добавляем строку
self.object:set_callback(callback.death, nil)

Дальше в функции
----------------------------------------------------------------------------------------------------------------------
function actor_binder:reinit()
После строки
self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
добавляем строку
self.object:set_callback(callback.death, self.death_callback, self)

Итак, у вас получилось вот так:
Код
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)
              self.object:set_callback(callback.death, self.death_callback, self)
end

А сейчас после end создаем новую функцию, то есть пишем все это:
Код
----------------------------------------------------------------------------------------------------------------------
function actor_binder:death_callback(victim, who)
       local slot4 = db.actor:item_in_slot(5)
       if slot4 then
        db.actor:activate_slot(0)
        --db.actor:transfer_item(slot4,db.actor)
        --[[
        db.actor:drop_item(slot4)
        spawn.inv("wpn_binoc")
        --]]
        --alife():release(alife():object(slot4:id()),true)
       end
       --qqq("death callback")
end


Все, идем дальше.

В функции
----------------------------------------------------------------------------------------------------------------------
function actor_binder:info_callback(npc, info_id)
После строки
-- Отметки на карте
level_tasks.process_info_portion(info_id)
добавляем строки
Код
if info_id == "ui_inventory" then
        inv.on_inv_open()
       elseif info_id == "ui_inventory_hide" then
        inv.on_inv_close()
       elseif info_id == "ui_trade" then
        inv.on_trade_open()
       elseif info_id == "ui_trade_hide" then
        inv.on_trade_close()
       elseif info_id == "ui_car_body" then
        inv.on_search_open()
       elseif info_id == "ui_car_body_hide" then
        inv.on_search_close()
       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)
              -- Состояние инвентаря
       if info_id == "ui_inventory" then
        inv.on_inv_open()
       elseif info_id == "ui_inventory_hide" then
        inv.on_inv_close()
       elseif info_id == "ui_trade" then
        inv.on_trade_open()
       elseif info_id == "ui_trade_hide" then
        inv.on_trade_close()
       elseif info_id == "ui_car_body" then
        inv.on_search_open()
       elseif info_id == "ui_car_body_hide" then
        inv.on_search_close()
       end
end


Пошли дальше.

В этой функции добавляем строчку, который я показал красным светом:
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_item_take (obj)
level_tasks.proceed(self.object)
kirag_take_drop.on_take(obj)

if rx_ai then rx_ai.actor_item_take(obj) end
if xrs_ai then xrs_ai.actor_item_take(obj) end

--game_stats.update_take_item (obj, self.object)
end
И в следующей функции поступаем также:
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_item_drop (obj)
level_tasks.proceed(self.object)
kirag_take_drop.on_drop(obj)

--game_stats.update_drop_item (obj, self.object)
end

Готово.

Дальше в функции
----------------------------------------------------------------------------------------------------------------------
function actor_binder:update(delta)
После строки
object_binder.update(self, delta)
Добавляем
if not self.updated then
if inv.init_dark_matter() then
self.updated = true
end
end

В этой же функции после строки
game_stats.update (delta, self.object)
добавляем строки
ammo_manager.update()

kirag_take_drop.on_update()

kirag_take_drop.autopickup_update()

if not inv.inv_mass then
inv.update_mass()
end


Вроде все, скрипт bind_stalker.script готов.

Осталось адаптировать скрипт xr_motivator.script.
В функции
function motivator_binder:death_callback(victim, who)
после строки
self:clear_callbacks()
добавляем строки
Код
if self.ammo_in_use and (string.sub(self.ammo_in_use,1,4) == "mag_" or string.sub(self.ammo_in_use,1,5) == "clip_" or string.sub(self.ammo_in_use,1,5) == "belt_") then
        local count = math.random(1,4)
        for i = 1,count do
         spawn.inv(self.ammo_in_use,self.object:id()) -- если совсем нет патронов - выдаем
        end
       end


Идем дальше:

В функции
--' Апдейт саундменеджера
после строки
self.object:set_tip_text_default()
end
добавляем вот это
Код
-- апдейт магазинов
       if ammo_manager and self.object:alive() then
        local wpn = self.object:item_in_slot(self.object:active_slot())
        if wpn then
         if not self.wpn or wpn:id() ~= self.wpn:id() then
          self.wpn = wpn
          if self.wpn then
           self.ammo = parse_data(system_ini():r_string(self.wpn:section(),"ammo_class"))
           local curr_ammo = ammo_manager.get_ammo_type(self.wpn:id()) + 1
           self.ammo_in_use = self.ammo[curr_ammo]
           if not self.object:object(self.ammo_in_use) then
            local another_ammo = nil
            for k,v in pairs (self.ammo) do
             if self.object:object(v) then -- вдруг есть другой подходящий БП
              another_ammo = true
              self.ammo_in_use = v -- проходим до конца, выбираем лучшее
             end
            end
            if not another_ammo then
             local count = math.random(1,4)
             for i = 1,count do
              spawn.inv(self.ammo_in_use,self.object:id()) -- если совсем нет патронов - выдаем
             end
            end
           end
           if string.sub(self.ammo_in_use,1,4) == "mag_" or string.sub(self.ammo_in_use,1,5) == "clip_" or string.sub(self.ammo_in_use,1,5) == "belt_" then
            self.mag_cap = system_ini():r_float(self.ammo_in_use,"mag_size") -- емкость магазина
            wpn:set_ammo_elapsed(self.mag_cap) -- оружие заряжено
           else
            self.mag_cap = nil
           end
          end        
          if not self.last_load then       
           self.last_load = wpn:get_ammo_in_magazine()
          end
         end
               
         local load = self.wpn:get_ammo_in_magazine()
         if self.mag_cap and load == 1 and self.last_load == 0 then -- зарядил, магазинное питание
          wpn:set_ammo_elapsed(self.mag_cap)
         end
         self.last_load = load
        end
       end
       if not self.object:alive() then
        if not self.death_mag_recharge then
         self.death_mag_recharge = 3 -- таймер установки заряда магазинов
        end
        if self.death_mag_recharge > 0 then
         if self.death_mag_recharge == 1 then
          local npc = self.object
          set_mag_charge(npc)
         end
         self.death_mag_recharge = self.death_mag_recharge - 1
        end
       end


Готово, идем дальше:

В функции
--' Проверка потери жизни
После строки(внимание, строки if xrs_grenade then xrs_grenade.npc_update(self) end, может у вас не быть)
if v:enabled(o) then
v:register(o)
end

break
end
end]]
if xrs_grenade then xrs_grenade.npc_update(self) end
end
добавляем
Код
[function set_mag_charge(npc)
       npc:iterate_inventory(
        function(dummy, item)
         local section = item:section()
          -- питание оружия из магазинов
         if string.sub(section,1,4) == "mag_" or string.sub(section,1,5) == "clip_" or string.sub(section,1,5) == "belt_" then
          local load = 1
          if math.random() < 0.2 then -- примерно каждый пятый магазин отстрелян на 10-90%
           load = math.random() * 0.8 + 0.1
          end
          item:set_condition(0.995*load)
         elseif section == "power_supply" then
          item:set_condition(math.random() * 0.75 + 0.25)
         end
        end
       ,npc)
end


Все, скрипт xr_motivator готов.
А остальные скрипты ammo_manager.script, inv.script, item_effects.script, kirag_take_drop.script и spawn.script кидаем в папку gamedata/script. А скрипт escape_dialog.script можете не копировать, лучше пусть остается скрипт вашей модификации.

Все, скриптами покончено, теперь перейдем конфигам.
Конфиги text и ui можете кидать с заменой файлов.
А вот над папкой weapons придется поработать.
Так, сначала открываем weapons.ltx.
Там, где прописаны конфиги оружия в конце добавляем строку
#include "dark_matter.ltx"

В функции
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; AMUNITION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
после строк
[ammo_base]:identity_immunities
;belt = true;
добавляем вот эти строки
Код
#include "ammo\magazines.ltx"
#include "ammo\9x18.ltx"
#include "ammo\9x19.ltx"
#include "ammo\9x39.ltx"
#include "ammo\12cal.ltx"
#include "ammo\57x28.ltx"
#include "ammo\357.ltx"
#include "ammo\545x39.ltx"
#include "ammo\556x45.ltx"
#include "ammo\762x25.ltx"
#include "ammo\762x39.ltx"
#include "ammo\762x51.ltx"
#include "ammo\762x54.ltx"
#include "ammo\792x57.ltx"
#include "ammo\1143x23.ltx"
#include "ammo\1270x99.ltx"
#include "ammo\1270x108.ltx"
#include "ammo\gauss_ammo.ltx"


Дальше удаляем все конфиги патронов в weapons.ltx до этих строчек:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Код
[ammo_og-7b]:ammo_base
GroupControlSection    = spawn_group
discovery_dependency =       
$spawn   = "weapons\ammo\ammo_og-7b" ; option for Level Editor
class   = A_OG7B
cform                   = skeleton
visual                  = weapons\ammo\ammo_og-7b.ogf
description    = enc_weapons1_ammo_ammo-og-7b
$prefetch   = 64

cost      = 1000

box_size  = 1

inv_name  = ammo-og-7b
inv_name_short    = ammo-og-7b
inv_weight  = 1.0

inv_grid_width  = 3
inv_grid_height  = 1
inv_grid_x   = 15
inv_grid_y   = 19

k_dist   = 1
k_disp   = 1
k_hit   = 1
k_impulse  = 1
k_pierce  = 1.25
impair   = 1.15
buck_shot  = 0
tracer   = off
wm_size         = 0.1

;могут ли боеприпасы быть неограниченными : 1 - могут, 0 - не могут
can_be_unlimited = true ;false

Как вы поняли, не трогаем только конфиги гранат подствольников, рпг, так же не трогаем конфиги аддонов для оружия(оптики, подсвольники, глушаки)

На этом работа с weapon.ltx закончена.

Перейдем к конфигам оружия. Если вы используете оружейный аддон(правозатворное оружие и тд.), то придется поработать.
И так, в каждом конфиге оружия придется написать следующее(не трогаем конфиги дробовиков и обрезов):
Например, берем конфиг ак-74, открываем его и находим строчки
ammo_mag_size = 30
и
ammo_class = ammo_5.45x39_fmj, ammo_5.45x39_ap ;
Вот эти строки нам надо и редактировать.
Приступим:

Значит так, перед строкой
ammo_mag_size = 30
вставим строку
ammo_mag_size = 1 ;(это значит, что к магазину можно одновременно цеплять только 1 магазин)
А на строке
ammo_class = ammo_5.45x39_fmj, ammo_5.45x39_ap ; вместо ammo пишем mag и количество патронов обоймы и в конце убираем точку запятой и ставим просто запятую.
Получиться так:
ammo_class = mag_30_5.45x39_fmj, mag_30_5.45x39_ap, mag_45_5.45x39_fmj, mag_45_5.45x39_ap,
После этой строки добавляем
; ammo_class = ammo_5.45x39_fmj, ammo_5.45x39_ap ;
И в итоге получиться вот так:
Код
ammo_mag_size    = 1 ; ammo_mag_size   = 30    ; clip (magazine) size
fire_modes    = 1, -1

ammo_class    = mag_30_5.45x39_fmj, mag_30_5.45x39_ap, mag_45_5.45x39_fmj, mag_45_5.45x39_ap, mag_75_5.45x39_fmj, mag_75_5.45x39_ap
;    ammo_class    = ammo_5.45x39_fmj, ammo_5.45x39_ap   ;

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

Идем дальше.
Остается только закинуть в папку weapons папку ammo и конфиг dark_matter.ltx.

Все, конфиги готовы.

А теперь кидаем папки meshes и sounds в gamedata.

А папку textures кидаем без папки ui, так как ui.icons.equpments у вас другой.
А теперь дело техники, открываем ui.icons.equpments фотошопом и переносим иконки обоймы на свой ui.icons.equpments, потом прописываем координаты. Все.

А ссылка на файл магазинное питание оружия(gamedata_magazines_v1.1_fixed) у нас на сайте есть. Удачи.
Если что я не правильно сделал, поправьте.
Сообщение отредактировал Mirage - Вторник, 21.05.2013, 10:13
  Злобная реклама
Воскресенье, 03.02.2013, 13:13
Статус:
Сообщений: 666
Регистрация: 09.06.2012
Форум » Архив » Устаревшие темы » Магазинное питание оружия (Попробуем разобраться, как адаптировать под различные моды)
  • Страница 1 из 1
  • 1
Поиск: