|
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 |
|
|
|
|