Многие думаю сталкивались с проблемой невозможности спавна "неживых" обьектов с помощью секции
[spawner] cond =
Есть один способ, заменяющий это. Нужно сделать следующее:
В xr_effects.script вставляем три эти скрипта:
Код
function spawn_object(actor, obj, p) local spawn_sect = p[1] if spawn_sect == nil then abort("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end local path_name = p[2] if path_name == nil then abort("Wrong path_name for 'spawn_object' function %s. For object %s", tostring(path_name), obj:name()) end if not level.patrol_path_exists(path_name) then abort("Path %s doesnt exist. Function 'spawn_object' for object %s ", tostring(path_name), obj:name()) end local ptr = patrol(path_name) local se_obj = alife():create(spawn_sect,ptr:point(),ptr:level_vertex_id(0),ptr:game_vertex_id(0)) end
function spawn_obj_in_zone(actor, obj, p) local spawn_sect = p[1] if spawn_sect == nil then abort("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end local zone_name = p[2] if zone_name == nil then abort("Wrong zone_name for 'spawn_object' function %s. For object %s", tostring(zone_name), obj:name()) end if db.zone_by_name[zone_name] == nil then abort("Zone %s doesnt exist. Function 'spawn_object' for object %s ", tostring(zone_name), obj:name()) end
local zone = db.zone_by_name[zone_name] local spawned_obj = alife():create( spawn_sect,zone:position(),zone:level_vertex_id(),zone:game_vertex_id()) end
function spawn_object_in(actor, obj, p) local spawn_sect = p[1] if spawn_sect == nil then abort("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end
local target_name = p[2] if target_name == nil then abort("Wrong target_name for 'spawn_object_in' function %s. For object %s", tostring(target_name), obj:name()) end local box = alife():object(target_name) if(box==nil) then abort("There is no such object %s", target_name) end local obj = alife():create(spawn_sect,vector(),0,0,box.id) end
Теперь в логике рестриктора можно делать следующее:
BeeRsek, ins33 же давно упростил этот код, взятый из ЗП.
Код
function spawn_object(actor, obj, p) local spawn_sect = p[1] local path_name = p[2] if level.patrol_path_exists(path_name) and spawn_sect ~= nil and path_name ~= nil then local ptr = patrol(path_name) local se_obj = alife():create(spawn_sect,ptr:point(),ptr:level_vertex_id(0),ptr:game_vertex_id(0)) end end
function spawn_object_in(actor, obj, p) local spawn_sect = p[1] local target_name = p[2] local box = alife():object(target_name) if spawn_sect ~= nil and target_name ~= nil and box ~=nil then local obj = alife():create(spawn_sect,vector(),0,0,box.id) end end
function spawn_obj_in_zone(actor, obj, p) local spawn_sect = p[1] local zone_name = p[2] local zone = db.zone_by_name[zone_name] if spawn_sect ~= nil and zone_name ~= nil and zone ~= nil then local spawned_obj = alife():create( spawn_sect,zone:position(),zone:level_vertex_id(),zone:game_vertex_id()) end end
function remove_actor_item_count(actor, npc, p) local item_section = p[1] local need_count = tonumber(p[2]) local has_count = 0 local count_tbl = {}
local function calc(temp, item) if item:section() == item_section then has_count = has_count + 1 count_tbl[has_count] = item:id() end end actor:iterate_inventory(calc,actor) for k,v in pairs( count_tbl ) do if k <= need_count then alife():release(alife():object(v),true) else break end end end
Теперь можно подправить и эти три скрипта, раз тему ещё не удалили. Может, кому и пригодится. Скрипты в xr_effects.script:
Код
function spawn_obj_in(actor, obj, p, amount) local spawn_sect = p[1] local target_name = p[2] local amount = tonumber(p[3]) local box = alife():object(target_name)
if db.actor then if not amount then amount = 1 end
for i = 1, amount do if spawn_sect ~= nil and target_name ~= nil and box ~= nil then local obj = alife():create(spawn_sect,vector(),0,0,box.id) end end end end
function spawn_obj_in_zone(actor, obj, p, amount) local spawn_sect = p[1] local zone_name = p[2] local amount = tonumber(p[3]) local zone = db.zone_by_name[zone_name]
if db.actor then if not amount then amount = 1 end for i = 1, amount do if spawn_sect ~= nil and zone_name ~= nil and zone ~= nil then local spawned_obj = alife():create(spawn_sect,zone:position(),zone:level_vertex_id(),zone:game_vertex_id())
end end end end
function spawn_object(actor, obj, p, amount) local spawn_sect = p[1] local path_name = p[2] local amount = tonumber(p[3]) local ptr = patrol(path_name)
if db.actor then if not amount then amount = 1 end for i = 1, amount do if level.patrol_path_exists(path_name) and spawn_sect ~= nil and path_name ~= nil then local se_obj = alife():create(spawn_sect,ptr:point(),ptr:level_vertex_id(0),ptr:game_vertex_id(0))
end end end end
Пример вызова из рестриктора: [logic] active = sr_idle
Спавн на графпойнт(гейм-вертекс) xr_effects.script:
Код
function spawn_ooo(actor,s, p, unt) local s,c,unt,g = p[1],p[2],p[3],game_graph() local lv = g:vertex(c) local a = lv:level_point() local b = lv:level_id() if not unt then unt = 1 end for i = 1, unt do if s ~= nil then alife():create(s,a,b,c) end end end
Вызов из логики: =spawn_ooo(boar_strong:320:2) где 320 - номер графпойнта,2 - колличество свиней Из диалога: function squa_on() xr_effects.spawn_ooo(actor, nil, {"medkit",320}) end
Соответственно, проверка расстояния Актора от графпойнта:В xr_conditions.script:
Код
function dist_to_graph_ge(a,m,p) local m = game_graph():vertex(p[1]):level_point() return m:distance_to_sqr(a:position()) >= p[2]*p[2] end
function dist_to_graph_le(a,m,p) local m = game_graph():vertex(p[1]):level_point() return m:distance_to_sqr(a:position()) <= p[2]*p[2] end
Пример вызова из рестриктора:{=dist_to_graph_ge(320:40)} 320 - номер граф-пойнта, 40 - расстояние Актора до геймвертекса. <img rel="usm" src="/sml/z/wink.gif" border="0" align="absmiddle" alt="wink" /> <img rel="usm" src="/sml/z/wink.gif" border="0" align="absmiddle" alt="wink" /> <img rel="usm" src="/sml/z/wink.gif" border="0" align="absmiddle" alt="wink" />
Добавлено (30.03.2018, 12:35) --------------------------------------------- Окно на запрос о переходе в ЗП по видеоуроку Stalker-Grez.
************************************************** 1.gamedata\configs\text\rus\ui_st_pda.xml ***************************************** <string id="level_exitus"> <text>Вы точно желаете перейти на другую локацию?</text> </string> <string id="Yes"> <text>Да</text> </string> <string id="Noy"> <text>Нет</text> </string> ******************************************************** 2.gamedata\configs\ui\map_spots.xml and map_spots_16.xml ******************************************************** <level_changer> <level_map spot="level_changer_spot" pointer="quest_pointer"/> <mini_map spot="level_changer_spot_mini" pointer="quest_pointer"/> </level_changer> <level_changer_spot width="11" height="11" stretch="1" alignment="c"> <texture>changer_point</texture> </level_changer_spot> <level_changer_spot_mini width="11" height="11" stretch="1" alignment="c"> <texture>mini_changer_point</texture> </level_changer_spot_mini> ************************************************** 3.gamedata\configs\ui\textures_descr\ui_common.xml ************************************************** <texture id="changer_point" x="728" y="577" width="50" height="50" /> <texture id="mini_changer_point" x="728" y="577" width="50" height="50" /> *************************************************************** 4.Новый файл ui_level_changer_dialog.xml в gamedata\configs\ui\ *************************************************************** <w> <back x="173" y="256" width="677" height="255"> <texture>ui_inGame2_message_box</texture> </back> <label x="328" y="353" width="25" height="15" complex_mode="0"> <text align="l" vert_align="c" font="graffiti32" r="175" g="175" b="175" a="255">level_exitus</text> </label> <btn_yes x="389" y="484" width="127" height="28" check_mode="0"> <window_name>button_yes</window_name> <text font="letterica18">Yes</text> <texture>ui_inGame2_Mp_bigbuttone</texture> </btn_yes> <btn_cancel x="521" y="484" width="127" height="28" check_mode="0"> <window_name>button_no</window_name> <text font="letterica18">Noy</text> <texture>ui_inGame2_Mp_bigbuttone</texture> </btn_cancel> </w> ************************************* 5.gamedata\configs\game_story_ids.ltx ************************************* Сносим всё. Пишем свои стори для отметок переходов на карте. Пример: [story_ids] 1 = "ch_esc_mar" 2 = "ch_mar_esc" Кидаем файл game_story_ids в СДК с заменой. Потом в СДК присвоим его рестриктору, из которого будем телепортироваться или ченджеру, если он внутри рестриктора. Но тогда не забываем о том, что Актор может пробежать метра 2, прежде чем включиться логика в рестрикторе. ******************************************* 6.Ставим 4 вейпонта с чекпойнтами для телепортов. Пример: ******************************************* esc_mar_yes_walk esc_mar_yes_look esc_mar_noy_walk esc_mar_noy_walk ****************************** 7. Логика рестриктора. Пример: ****************************** [logic] active = sr_idle
[sr_idle@1] on_info = {+changer_info_yes} sr_idle %-changer_info_yes =teleport_actor(esc_mar_yes_walk:esc_mar_yes_look)% on_info2 = {+changer_info_noy} sr_idle %-changer_info_noy =teleport_actor(esc_mar_noy_walk:esc_mar_noy_look)% ;можно добавить проверу на выброс {!surge_started} или ещё на что-нибудь... ************************************************************** 8.В xr_effects.script вызов функции окна из урока Stalker-Grez ************************************************************** function ch_lv_st() level_tasks.StartWnd() end ************************************************************************************************************ 9. В pda.script активация отметок переходов в ПДА. В скрипт function fill_primary_objects(), в самый конец: ************************************************************************************************************ level_tasks.add_lchanger_location() ********************************************************************************************************** 10.Сам файл level_tasks.script. В нём оставим пару функций из ЧН(ТЧ) и добавим скипт вызова окна на запрос о разрешении на переход: ************************
Код
function add_lchanger_location() local sim = alife() if sim then local obj = sim:story_object(1) set_lchanger_mapspot(obj, "level_changer", "st_lchanger_to_escape")
obj = sim:story_object(2) set_lchanger_mapspot(obj, "level_changer", "st_lchanger_to_garbage") end end
function set_lchanger_mapspot(obj, spot, hint) if obj then local obj_id = obj.id local ce_obj = level.object_by_id(obj_id) if ce_obj and level.map_has_object_spot(obj_id, spot) == 0 then level.map_add_object_spot(obj_id, spot, hint) end end end
-- ************************************* local Form = nil function StartWnd() if Form == nil then Form = level_tasks.LevelChange_Question() end Form:__Show() end
class "LevelChange_Question" (CUIScriptWnd) function LevelChange_Question:__init() super() self:__Constructor() self:__AddCallbacks() end
function LevelChange_Question:__Constructor() self:SetWndRect(Frect():set(0,0,1024,768)) local xml = CScriptXmlInit() xml:ParseFile("ui_level_changer_dialog.xml") xml:InitStatic("back", self) self.static=xml:InitStatic("label", self) self.bt_yes=xml:Init3tButton("btn_yes", self) self:Register(self.bt_yes, "btn_yes") self.bt_no=xml:Init3tButton("btn_cancel", self) self:Register(self.bt_no, "btn_cancel") end
function LevelChange_Question:__AddCallbacks() self:AddCallback("btn_yes", ui_events.BUTTON_CLICKED, self.__Yes, self) self:AddCallback("btn_cancel", ui_events.BUTTON_CLICKED, self.__No, self) end
function LevelChange_Question:__Show() self:ShowDialog(true) end
function LevelChange_Question:__Destructor() self:HideDialog() end
function LevelChange_Question:__Yes() db.actor:give_info_portion("changer_info_yes") self:__Destructor() end
function LevelChange_Question:__No() db.actor:give_info_portion("changer_info_noy") self:__Destructor() end
function LevelChange_Question:OnKeyboard(dik, keyboard_action) CUIScriptWnd.OnKeyboard(self,dik,keyboard_action) local bind = dik_to_bind(dik) if bind == key_bindings.kQUIT then self:__No() end return true end
Инфопоршни changer_info_yes и changer_info_noy в ЗП, вроде можно не регистировать.
Сообщение отредактировал Arist - Пятница, 30.03.2018, 12:38