Gaz24 6 Опубликовано 16 Декабря 2012 Эксперементировал со скриптами мода "Скриптовая эмуляция невидимых слотов". Вместо ПДА взял слот для детектора. Если убрать детектор в рюкзак все нормально, а когда поместить его обратно в слот, то возникает безлоговый вылет. Что делать? local debug = false --true -- система размещения кнопок ( true - вкл.\ false - выкл.)local rec_wnd = nillocal initial = falselocal TBtn = {}-- нож бинокль болт ПДА фонарик -- координаты кнопок {x,y}local slots = { {80,50},{220,50},{4000,50},{730,50},{880,50}}----------------------------------------------------------------------------------class "BkgrWnd" (CUIScriptWnd)function BkgrWnd:__init(owner) super()self.owner = ownerself:Init(0, 0, 1024, 768)self.ClickBtn={}self.ClickBtn[1] = function()local item = db.actor:item_in_slot(0)if item then spawn_item_in_inv("fake_"..item:section()) del_item(item:id()) end TBtn["check_button_1"]:Show(false)endself.ClickBtn[2]=function()local item = db.actor:item_in_slot(4)if item then spawn_item_in_inv("fake_"..item:section()) del_item(item:id()) end TBtn["check_button_2"]:Show(false)endself.ClickBtn[3]=function()news_manager.send_tip(db.actor, "руки прочь от болта!" )endself.ClickBtn[4]=function()local item = db.actor:item_in_slot(8)if item then spawn_item_in_inv(item:section()) del_item(item:id()) end TBtn["check_button_4"]:Show(false)endself.ClickBtn[5]=function()local item = db.actor:object("device_torch")if item then spawn_item_in_inv("fake_device_torch") del_item(item:id()) end TBtn["check_button_5"]:Show(false)endself:InitControls()endfunction BkgrWnd:__finalize() endfunction BkgrWnd:InitControls()clear_table(TBtn)self.bkgr_static=CUIStatic()self.bkgr_static:Init("ui\\ui_inv_quick_slots",10, 0, 1024, 100)self.bkgr_static:ClipperOn()self.stat = CUIStatic()self.stat:AttachChild(self.bkgr_static)self.stat:Init(0, 0, 1024, 768)self.owner:AttachChild(self.stat)for k,v in pairs (slots) dolocal name="check_button_"..kself.btn = CUIButton()self.btn:SetAutoDelete(false)self.btn:SetWindowName(name)self:Register(self.btn)self.stat:AttachChild(self.btn)TBtn[name]= self.btninit_btn(k)self:AddCallback(name,ui_events.WINDOW_LBUTTON_DB_CLICK, self.ClickBtn[k], self)endinitial = trueendfunction BkgrWnd:ClickBtnStepUp()self.step=self.step*2if self.step>200 then self.step=128 end--news_manager.send_tip(db.actor,"шаг= "..self.step)self.btn:SetText("кнопка "..self.num_btn.." шаг "..self.step)endfunction BkgrWnd:ClickBtnStepDn()self.step=self.step/2if self.step==1 then self.step=2 end--news_manager.send_tip(db.actor,"шаг= "..self.step)self.btn:SetText("кнопка "..self.num_btn.." шаг "..self.step)endfunction BkgrWnd:ClickNxtBtn()self.num_btn=self.num_btn+1if self.num_btn>#slots then self.num_btn=1 endself.btn:SetText("кнопка "..self.num_btn.." шаг "..self.step)--news_manager.send_tip(db.actor,"скорректируем положение кнопки "..self.num_btn)endfunction BkgrWnd:ClickBtnUp()slots[self.num_btn][2]=slots[self.num_btn][2]-self.stepif slots[self.num_btn][2]<0 then slots[self.num_btn][2]=768+slots[self.num_btn][2] endinit_btn(self.num_btn)endfunction BkgrWnd:ClickBtnDwn()slots[self.num_btn][2]=slots[self.num_btn][2]+self.stepif slots[self.num_btn][2]>768 then slots[self.num_btn][2]=-768+slots[self.num_btn][2] endinit_btn(self.num_btn)endfunction BkgrWnd:ClickBtnLft()slots[self.num_btn][1]=slots[self.num_btn][1]-self.stepif slots[self.num_btn][1]<0 then slots[self.num_btn][1]=1024+slots[self.num_btn][1] endinit_btn(self.num_btn)endfunction BkgrWnd:ClickBtnRt()slots[self.num_btn][1]=slots[self.num_btn][1]+self.stepif slots[self.num_btn][1]>1024 then slots[self.num_btn][1]=-1024+slots[self.num_btn][1] endinit_btn(self.num_btn)end-- инициализация с учетом размеров иконки статикаfunction init_btn(num,sec)local function sections(num)if num==1 thenlocal item=db.actor:item_in_slot(0)if item then return item:section() else return endelseif num==2 thenlocal item=db.actor:item_in_slot(4)if item then return item:section() else return endelseif num==3 thenelseif num==4 thenlocal item=db.actor:item_in_slot(8)if item then return item:section() else return endelseif num==5 thenlocal item=db.actor:item_in_slot(9)if item then return "device_torch" else return endendendlocal btn=TBtn["check_button_"..num]if not btn then rec_wnd = BkgrWnd(level.main_input_receiver()) endbtn=TBtn["check_button_"..num]local sect = sec or sections(num)if sect thenlocal ini=system_ini()local x=ini:r_u32(sect, "inv_grid_x")*50local y=ini:r_u32(sect, "inv_grid_y")*50local width=ini:r_u32(sect, "inv_grid_width")*50local height=ini:r_u32(sect, "inv_grid_height")*50btn:InitTexture("ui\\ui_icon_equipment")btn:SetOriginalRect(x,y,width,height)btn:SetStretchTexture(true)local h=50 -- высота кнопки 50 пикселовlocal w=h*width/height -- ширина пропорциональна соотношению высоты и ширины инвентарной иконки.btn:Init(slots[num][1]-w/2,slots[num][2]-h/2,w,h)btn:Show(true)elsebtn:Init(slots[num][1],slots[num][2],0,0)endendfunction BkgrWnd:ShowWnd()if initial and rec_wnd.stat~= nil thenrec_wnd.stat:Show(true)endendfunction BkgrWnd:HideWnd()if initial and rec_wnd.stat~= nil thenrec_wnd.stat:Show(false)endendfunction BkgrWnd:DetachWnd()self.owner:DetachChild(self.stat)-- self:AttachChild(self.stat)initial = falseend--------------------------------------------------------------------------function on_eat(sect)local items_for_0_slot={ -- кулаки,ножи,перчатки...["fake_wpn_knife"]=true,["fake_wpn_fist"]=true,["fake_wpn_fist_m"]=true}if items_for_0_slot[sect] thenreinit_button_1(string.sub(sect,6,-1)) returnendlocal items_for_4_slot={ -- бинокли...["fake_wpn_binoc"]=true,["fake_wpn_binoc1"]=true}if items_for_4_slot[sect] thenreinit_button_2(string.sub(sect,6,-1)) returnendif sect=="fake_device_torch" thenif db.actor:object("device_torch") thenspawn_item_in_inv("fake_device_torch")elsespawn_item_in_inv("device_torch") init_btn(5,"device_torch")endendendfunction reinit_button_1(sect)local item=db.actor:item_in_slot(0)if item thendb.actor:drop_item(item) spawn_item_in_inv("fake_"..item:section())del_item(item:id())endspawn_item_in_inv(sect)init_btn(1,sect)endfunction reinit_button_2(sect)local item=db.actor:item_in_slot(4)if item thendb.actor:drop_item(item) spawn_item_in_inv("fake_"..item:section())del_item(item:id())endspawn_item_in_inv(sect)init_btn(2,sect)endfunction spawn_item_in_inv( sect )alife():create(sect,db.actor:position(),db.actor:level_vertex_id(),db.actor:game_vertex_id(),0)endfunction del_item(id)if id thenlocal sobj=alife():object(id)if sobj then alife():release(sobj,true) endendend---------------------------------------------------------------------------------------------function on_info(info_id)if info_id == "ui_inventory" thenif not initial thenrec_wnd = BkgrWnd(level.main_input_receiver())endif not rec_wnd.stat:IsShown() thenrec_wnd:ShowWnd()endelseif info_id == "ui_inventory_hide" thenif rec_wnd thenrec_wnd:DetachWnd()endendend Поделиться этим сообщением Ссылка на сообщение
Gaz24 6 Опубликовано 19 Декабря 2012 (изменено) С вопросом ошибся темой. ColR_iT Изменено 19 Декабря 2012 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
Gaz24 6 Опубликовано 31 Августа 2014 (изменено) Всем привет.Хотел добавить зависимость выпадения вещей после смерти НПС от ранга. Но поскольку я в скриптинге не очень опытный, то возникают баги. --' Ключем является группировка персонажа. Значением является таблица, содержашая имена секций предметов.local item_by_community = {}--' Зависимости в спауне предметов. Предмет спауниться только если есть хотя бы один из зависимых.local item_dependence = {}--' Множители и минимаксы для выпадения вещей в зависимости от уровняlocal mul_by_level = {}local count_by_level = {}--' Множители и минимаксы для выпадения вещей в зависимости от рангаlocal mul_by_rank = {}local count_by_rank = {}--' Предметы, которые нельзя удалять (квестовые например)local always_keep_item = {}--' Предметы, относящиеся к патронам. Их надо спаунить другим методом.local ammo_sections = {}local death_ini = ini_file("misc\\death_generic.ltx")function init_drop_settings()local community_list = { "stalker", "dolg", "freedom", "bandit", "military", "zombied", "ecolog", "killer", "monolith", "arena_enemy", "actor_dolg" }for k,v in pairs(community_list) do--' Необходимо заполнить таблицуitem_by_community[v] = {}if death_ini:section_exist(v) thenlocal n = death_ini:line_count(v)local id, value = "", ""for i=0,n-1 doresult, id, value = death_ini:r_line(v,i,"","")item_by_community[v][id] = 100*tonumber(value)endendend--' Заполняем таблицу зависимостейlocal n = death_ini:line_count("item_dependence")local id, value = "", ""for i=0,n-1 doresult, id, value = death_ini:r_line("item_dependence",i,"","")item_dependence[id] = {}local vvv = parse_names(value)for k,v in pairs(vvv) doitem_dependence[id][v] = trueendend--' Множители и минимаксы для выпадения вещей в зависимости от уровняlocal level_name = level.name()if not death_ini:section_exist(level_name) thenlevel_name = "default"endlocal n = death_ini:line_count(level_name)local id, value = "", ""for i=0,n-1 doresult, id, value = death_ini:r_line(level_name,i,"","")mul_by_level[id] = tonumber(value)end--' Множители и минимаксы для выпадения вещей в зависимости от рангаlocal character_rank = db.actor:rank()if not death_ini:section_exist(character_rank) thencharacter_rank = "novice"endlocal n = death_ini:line_count(character_rank)local id, value = "", ""for i=0,n-1 doresult, id, value = death_ini:r_line(character_rank,i,"","")mul_by_rank[id] = tonumber(value)endlocal item_count_section = "item_count_" .. level.get_game_difficulty()local n = death_ini:line_count(item_count_section)for i=0,n-1 doresult, id, value = death_ini:r_line(item_count_section,i,"","")--' Нужно распарсить value в два значенияlocal t = parse_nums(value)if t[1] == nil thenabort("Error on [death_ini] declaration. Section [%s], line [%s]", item_count_section, tostring(id))endlocal min = t[1]local max = t[2]if max == nil thenmax = minendif mul_by_level[id] == nil thenmul_by_level[id] = 0endif mul_by_rank[id] == nil thenmul_by_rank[id] = 0endmin = tonumber(min) * (mul_by_level[id] + mul_by_rank[id])max = tonumber(max) * (mul_by_level[id] + mul_by_rank[id])count_by_level[id] = {min = min, max = max}count_by_rank[id] = {min = min, max = max}end--' Предметы, которые нельзя удалять (квестовые например)local n = death_ini:line_count("keep_items")for i=0,n-1 doresult, id, value = death_ini:r_line("keep_items",i,"","")if value == "true" thenalways_keep_item[id] = trueendend--' Предметы, относящиеся к патронам. Их надо спаунить другим методом.ammo_sections = {}local n = death_ini:line_count("ammo_sections")local id, value = "", ""for i=0,n-1 doresult, id, value = death_ini:r_line("ammo_sections",i,"","")ammo_sections[id] = trueendendclass "drop_manager"function drop_manager:__init(npc)self.npc = npcendfunction drop_manager:create_release_item()--' Спрашиваем у серверного объекта генерились ли предметыlocal se_obj = alife():object(self.npc:id())if se_obj.death_droped == true thenreturnendse_obj.death_droped = true--' Запускаем итератор на удаление предметовself.npc:iterate_inventory(keep_item, self.npc)--' Проверка на отсутствие спауна лутаlocal ini = self.npc:spawn_ini()if ini and ini:section_exist("dont_spawn_loot") thenreturnend--' Доспавниваем необходимое количество итемов:--' Необходимо составить список объектов которые могут быть заспавнены для персонажаlocal spawn_items = item_by_community[self.npc:character_community()]for k,v,t in pairs(spawn_items) do--' По каждому объекту необходимо получить зависимостиif check_item_dependence(self.npc, k) == true then--' По каждому объекту необходимо получить количествоlocal number = math.ceil(math.random(count_by_level[k].min, count_by_level[k].max))--' Необходимо заспавнить нужное количество.create_items(self.npc, k, number, v)endendend--' Функция вызывается для каждого предмета, если вернет false то предмет удалится.function keep_item(npc, item)if item==nil or alife():object(item:id())==nil then return endlocal section = item:section()if section == "bolt" thenreturn falseendif always_keep_item[section] == true thenreturn trueendlocal item_id = item:id()local item_in_slot = npc:item_in_slot(1)if item_in_slot ~= nil anditem_in_slot:id() == item_idthen--' Тут надо уменьшить кондишн оружияitem:set_condition((math.random(15)+75)*item:condition()/100)return trueenditem_in_slot = npc:item_in_slot(2)if item_in_slot ~= nil anditem_in_slot:id() == item_idthen--' Тут надо уменьшить кондишн оружияitem:set_condition((math.random(15)+75)*item:condition()/100)return trueendalife():release(alife():object(item:id()), true)endfunction set_weapon_drop_condition(item)local condition = (math.random(15)+75)/100--printf("condition [%s]", tostring(condition))item:set_condition(condition)end--' Функция спавнит необходимое число предметовfunction create_items(npc, section, number, rnd)--'printf("create %s of %s", tostring(number), tostring(section))if ammo_sections[section] == true thenif number > 0 thense_respawn.create_ammo(section,npc:position(),npc:level_vertex_id(),npc:game_vertex_id(),npc:id(),number)endelsefor i=1,number do--' Проверяем вероятность появить каждый объект в отдельностиif math.random(100) <= rnd thenalife():create(section,npc:position(),npc:level_vertex_id(),npc:game_vertex_id(),npc:id())endendendend--' Функция проверяет есть ли хоть один из зависимых объектов у персонажаfunction check_item_dependence(npc, section)if item_dependence[section] == nil thenreturn trueendlocal d_flag = truefor k,v in pairs(item_dependence[section]) dolocal obj = npc:object(k)if obj ~= nil and npc:marked_dropped(obj) ~= true thenreturn trueendd_flag = falseendreturn d_flagendФункця работает, но дело в том, что учитывается ранг Актора, а не НПС. А вот как сделать, чтобы учитывался ранг НПС, я не знаю. Изменено 31 Августа 2014 пользователем Gaz24 Поделиться этим сообщением Ссылка на сообщение
Gaz24 6 Опубликовано 25 Октября 2015 (изменено) Всем привет. Пытался переадаптировать схему боя НПС с ножом из ЗП в ТЧ. В итоге НПС достает нож, смотрит на ГГ и больше ничего не делает. Возникли вопросы:1. Кто-нибудь разбирал этот скрипт?2. Возможно подправить это баг?Вот еще файл скрипта ---- Rulix aka Bak --- 8.3.2010 function printf(s, ...)-- rx_ai.printf("kn:"..s,...)-- get_console():execute("flush")endlocal kn_ini = ini_file("misc\\rx_knife.ltx")local knife_sets = {forbiddens = {weapons = {},factions = {},npcs = {}},communities = {},ranks = {},check_prd = rx_utils.read_from_ini(kn_ini,"main","check_period",1001),fire_dist = rx_utils.read_from_ini(kn_ini,"main","fire_dist",1.5),enabled = rx_utils.read_from_ini(kn_ini,"main","enabled",false,0)}function init()if not knife_sets.enabled thenkn_ini = nilreturnendlocal ranks = {"novice","experienced","veteran","master"}for k,v in ipairs(ranks) doif kn_ini:section_exist(v) thenknife_sets.ranks[v] = {rate = rx_utils.read_from_ini(kn_ini,v,"rate",1)}endendlocal communities = { "stalker", "dolg", "freedom", "bandit", "military", "ecolog", "killer", "monolith" }for k,v in ipairs(communities) doknife_sets.communities[v] = {rate_add = rx_utils.read_from_ini(kn_ini,v,"rate_add",0),courage = rx_utils.read_from_ini(kn_ini,v,"courage",1),attack_wounded = rx_utils.read_from_ini(kn_ini,v,"attack_wounded",0),mutant_hunt = rx_utils.read_from_ini(kn_ini,v,"mutant_hunt",true,0) or nil}endknife_sets.forbiddens.weapons = rx_utils.parse_list(kn_ini,"main","forbidden_weapons",true)knife_sets.forbiddens.factions = rx_utils.parse_list(kn_ini,"main","forbidden_factions",true)knife_sets.forbiddens.npcs = rx_utils.parse_list(kn_ini,"main","forbidden_npcs",true)kn_ini = nilknife_sets.inited = trueendlocal kill_wounded = 0local sneak_attack = 1local close_attack = 2local mutant_hunt = 3local mutant_defend = 4local mutant_hunt_clsids = {[clsid.bloodsucker_s] = true,[clsid.boar_s] = true,-- [clsid.dog_s] = true,[clsid.flesh_s] = true,-- [clsid.pseudodog_s] = true,-- [clsid.burer_s] = true,-- [clsid.cat_s] = true,-- [clsid.chimera_s] = true,[clsid.controller_s] = true,-- [clsid.fracture_s] = true,-- [clsid.poltergeist_s] = true,-- [clsid.gigant_s] = true,-- [clsid.zombie_s] = true,-- [clsid.snork_s] = true,-- [clsid.tushkano_s] = true,[clsid.psy_dog_s] = true,-- [clsid.psy_dog_phantom_s] = true}}local mutant_defend_clsids = {-- [clsid.bloodsucker_s] = true,[clsid.boar_s] = true,-- [clsid.dog_s] = true,[clsid.flesh_s] = true,[clsid.pseudodog_s] = true,-- [clsid.burer_s] = true,[clsid.cat_s] = true,-- [clsid.chimera_s] = true,-- [clsid.controller_s] = true,[clsid.fracture_s] = true,-- [clsid.poltergeist_s] = true,-- [clsid.gigant_s] = true,-- [clsid.zombie_s] = true,-- [clsid.snork_s] = true,[clsid.tushkano_s] = true,[clsid.psy_dog_s] = true,-- [clsid.psy_dog_phantom_s] = true}}targets = {}local function remove_target(npc_id,st)if st.target and targets[st.target] == npc_id thentargets[st.target] = nilendst.target = nilendclass "evaluator_knife_attack" (property_evaluator)function evaluator_knife_attack:__init(npc,name,storage) super (nil,name)self.st = storageself.st.delay = 0self.st.timer = 0self.check_timer = 0local comm = npc:character_community()if self.attack_wounded == nil thenself.attack_wounded = math.random() < knife_sets.communities[comm].attack_woundedendif not self.courage thenself.courage = math.random(25,npc:character_rank()/4+51)endself.courage = self.courage*knife_sets.communities[comm].courageself.cmhunt = knife_sets.communities[comm].mutant_hunt-- rx_ai.printf("knife_init[%s]:kn_aw %s, courage %s, rank %s",npc:character_name(),tostring(self.attack_wounded),self.courage,npc:character_rank())rx_ai.subscribe_for_events(npc,self)endfunction evaluator_knife_attack:evaluate()local npc = self.objectif rx_utils.IsTrader(npc) thenreturn falseendlocal wm = rx_wmgr and rx_wmgr.get_wm(npc)local knife = npc:object("wpn_knife")if not knife or npc:animation_count() ~= 0 then-- printf("evaluator_knife_attack[%s]:not knife or anims",npc:character_name())remove_target(npc_id,self.st)return falseendlocal npc_id,tg = npc:id(),time_global()if self.st.delay > tg thenremove_target(npc_id,self.st)-- printf("evaluator_knife_attack[%s]:delay",npc:character_name())return falseendlocal be = npc:best_enemy()if not be thenremove_target(npc_id,self.st)return falseendlocal be_id = be:id()local target = self.st.target and level.object_by_id(self.st.target)if not (target and target:alive()) then-- printf("evaluator_knife_attack[%s]:not target",npc:character_name())remove_target(npc_id,self.st)endlocal npc_pos = npc:position()if target then-- printf("evaluator_knife_attack[%s]:target",npc:character_name())local target_pos = be:position()local dist = target_pos:distance_to(npc_pos)if targets[self.st.target] thenif targets[self.st.target] ~= npc_id thenprintf("evaluator_knife_attack[%s]:target gette",npc:character_name())remove_target(npc_id,self.st)elseif self.st.target ~= be_id and dist > 3 or not npc:accessible(target_pos) thenprintf("evaluator_knife_attack[%s]:target not access",npc:character_name())remove_target(npc_id,self.st)elseif self.st.type == kill_wounded and dist > 5 thenremove_target(npc_id,self.st)self.st.delay = tg+15000return falseelseif self.st.type == sneak_attack and target:see(npc) and dist > self.courage/20 thenself.st.type = close_attackreturn trueelseif self.st.type == close_attack and dist > self.courage/10 thenremove_target(npc_id,self.st)self.st.delay = tg+15000return falseelseif self.st.type == mutant_hunt and dist > 15 thenremove_target(npc_id,self.st)self.st.delay = tg+12000return falseelseif self.st.type == mutant_defend and dist > 12 or npc.health < 0.2 then -- or not (target:get_enemy() and target:get_enemy():id() == npc_id)remove_target(npc_id,self.st)self.st.delay = tg+12000return falseendreturn trueendelseif dist > 12 thenprintf("evaluator_knife_attack[%s]:target dist > 12",npc:character_name())self.st.target = nilendendendif self.check_timer > tg thenreturn target ~= nilendself.check_timer = tg+knife_sets.check_prdlocal be_pos = be:position()local dist = npc_pos:distance_to(be_pos)if targets[be_id] or (xr_wounded.is_wounded(be) and not self.attack_wounded) or dist > 10 or not npc:accessible(be_pos) then-- printf("evaluator_knife_attack[%s]:not access %s %s %s %s",npc:character_name(),tostring(targets[be_id]),tostring((xr_wounded.is_wounded(be) and not self.attack_wounded)),tostring(dist > 15),tostring(not npc:accessible(be_pos)))return falseendlocal be_see_me,me_see_be = be:see(npc),npc:see(be)if IsStalker(be) thenif xr_wounded.is_wounded(be) thenif self.attack_wounded and me_see_be and dist < 3.5 thenself.st.target = be_idself.st.type = kill_woundedreturn trueendreturn falseendif me_see_be and not be_see_me and self.courage > 40 and npc:body_state() == move.crouch and dist < 5 and npc.health > 0.5 then-- printf("sneak_attack[%s]:return true",npc:character_name())self.st.target = be_idself.st.type = sneak_attackreturn trueendif self.courage > 33+5*dist and me_see_be thenlocal npc_wpn,be_wpn = npc:active_item(),be:active_item()if not (be_wpn and rx_utils.item_is_fa(be_wpn) and npc_wpn and npc_wpn:section() ~= "wpn_knife" and npc_wpn:get_ammo_in_magazine() ~= 0 and be_wpn:get_ammo_in_magazine() ~= 0) then-- printf("close_attack[%s]:return true",npc:character_name())self.st.target = be_idself.st.type = close_attackself.st.timer = self.st.timer+6000return trueendendelselocal bee = be:get_enemy()-- printf("monster[%s]: %s %s",npc:character_name(),tostring(not (be_see_me and be:get_enemy() and be:get_enemy():id() == npc_id)),tostring(npc.health > 0.8))if self.cmhunt and mutant_hunt_clsids[be:clsid()] and self.courage > 35+5*dist and not (be_see_me and bee and bee:id() == npc_id) and npc.health > 0.8 then-- printf("mutant_hunt[%s]:return true",npc:character_name())self.st.target = be_idself.st.type = mutant_huntself.st.timer = self.st.timer+6000return trueelseif mutant_defend_clsids[be:clsid()] and dist < 6 and self.courage > 40+dist and (be_see_me and bee and bee:id() == npc_id) and npc.health > 0.2 then-- printf("mutant_defend[%s]:return true",npc:character_name())self.st.target = be_idself.st.type = mutant_defendself.st.timer = self.st.timer+4000return trueendendreturn falseendfunction evaluator_knife_attack:death_callback(who)if self.object thenremove_target(self.object:id(),self.st)endendclass "evaluator_knife_defend" (property_evaluator)function evaluator_knife_defend:__init(npc,name,storage) super (nil,name)self.st = storageendfunction evaluator_knife_defend:evaluate()return falseendclass "action_knife_attack" (action_base)function action_knife_attack:__init(npc,action_name,storage) super (nil,action_name)self.st = storageself.rank = ranks.get_obj_rank_name(npc)self.comm = npc:character_community()self.rate = 1000/(knife_sets.ranks[self.rank].rate+knife_sets.communities[self.comm].rate_add)endfunction action_knife_attack:initialize()action_base.initialize(self)local npc = self.objectprintf("knife_attack[%s]:init",npc:character_name())self.st.timer = time_global()+30000self.start_time = time_global()self.fire_time = 0self.mental_time = 0if rx_wmgr thenlocal wm = rx_wmgr.get_wm(npc)-- local knife = wm:get_best_weapon(1)-- wm:return_items(knife and knife:id() or 0)wm:disable(self.st.timer)endnpc:set_desired_position()npc:set_desired_direction()npc:set_mental_state(anim.danger)npc:set_movement_type(move.run)-- state_mgr.set_state(npc,"assault")state_mgr.set_state(npc,"idle")targets[self.st.target] = npc:id()if self.st.type == kill_wounded then--xr_sound.set_sound_play(targets[self.st.target],"kill_wounded")endself.ddr = math.random() > 0.5endfunction action_knife_attack:execute()action_base.execute(self)local npc,tg = self.object,time_global()local npc_id = npc:id()if self.st.timer < tg thenremove_target(npc_id,self.st)self.st.delay = tg+10000printf("knife_attack[%s]:timer < tg",npc:character_name())returnendlocal target = level.object_by_id(self.st.target)local dist = npc:position():distance_to(target:position())local knife = npc:object("wpn_knife")local dir = target:position()dir:sub(npc:position())npc:set_sight(look.direction,dir)local acti = npc:active_item()acti = acti and acti:section() == "wpn_knife"if acti and (dist < knife_sets.fire_dist or self.st.type == mutant_defend and dist < knife_sets.fire_dist*1.5) then-- printf("attack[%s]:set fire",npc:character_name())npc:set_sight(look.fire_point,target:bone_position("bip01_neck"))if self.fire_time < tg thennpc:set_item(object.fire1,knife,1,self.rate)self.fire_time = tg+self.rateendif self.st.type == kill_wounded then-- npc:set_dest_level_vertex_id(npc:level_vertex_id())npc:set_movement_type(move.stand)npc:set_body_state(move.crouch)endelseif not (self.st.type == kill_wounded or self.st.type == sneak_attack or IsMonster(target)) then--xr_sound.set_sound_play(npc_id,"knife_attack")endif self.st.type ~= mutant_defend thennpc:set_movement_type(move.run)endnpc:set_item(object.aim1,knife)endif not acti thenif self.start_time+4000 < tg thenremove_target(npc_id,self.st)self.st.delay = tg+15000printf("knife_attack[%s]:timer < tg",npc:character_name())returnendnpc:set_mental_state(anim.danger)elseif self.st.type == sneak_attack thennpc:set_body_state(move.crouch)npc:set_mental_state(anim.danger)if dist > 6 and target:see(npc) thenprintf("sneak_attack[%s]:abort",npc:character_name())remove_target(npc_id,self.st)returnendelseif self.st.type == mutant_hunt thennpc:set_body_state(move.standing)if self.mental_time < tg thenif dist < 3 and self.mental ~= anim.danger thenself.mental_time = tg+900self.mental = anim.dangerelseif self.mental ~= anim.panic thenself.mental_time = tg+1500self.mental = anim.panicendnpc:set_mental_state(self.mental)end-- printf("mutant_hunt[%s]:send",npc:character_name())elseif self.st.type == close_attack thennpc:set_body_state(move.standing)npc:set_mental_state(anim.danger)-- printf("close_attack[%s]:send",npc:character_name())elseif self.st.type == mutant_defend thennpc:set_body_state(move.standing)npc:set_mental_state(anim.danger)if dist < 3.5 thennpc:set_movement_type(move.run)elsenpc:set_movement_type(move.walk)end-- printf("mutant_defend[%s]:send",npc:character_name())endlocal vertex = self.st.type == mutant_defend and get_dodge_vertex(npc,target,self.ddr) or target:level_vertex_id()utils.send_to_nearest_accessible_vertex(npc,vertex)endfunction action_knife_attack:finalize()local npc = self.objectprintf("knife_attack[%s]:fin",npc:character_name())if rx_wmgr thenrx_wmgr.get_wm(npc):enable()endif not npc:best_enemy() thennpc:set_item(object.idle,npc:object("wpn_knife"))state_mgr.set_state(npc,"guard")endnpc:set_sight(look.direction,npc:direction())remove_target(npc:id(),self.st)self.mental = nilself.ddr = nilaction_base.finalize(self)endclass "action_knife_defend" (action_base)function action_knife_defend:__init (npc,action_name,storage) super (nil,action_name)self.st = storageendfunction action_knife_defend:initialize()action_base.initialize(self)self.wm = db.storage[npc:id()].wmself.wm:set_weapon(npc:object("wpn_knife"))self.wm.disabled_temp = trueendfunction action_knife_defend:execute()action_base.execute(self)endfunction action_knife_defend:finalize()action_base.finalize(self)endfunction get_dodge_vertex(s,o,d)local dir = o:position():sub(s:position())dir = vector_rotate_y(dir,d and 50 or 310)return s:vertex_in_direction(s:level_vertex_id(),dir,3)endfunction npc_update(npc)if knife_sets.enabled thenlocal knife = npc:object("wpn_knife")if not knife thenalife():create("wpn_knife",npc:position(),npc:level_vertex_id(),npc:game_vertex_id(),npc:id())endendendevid_knife_attack=rx_ai.base_id+35--evid_knife_defend=evid_knife_attack+1actid_knife_attack=evid_knife_attack--actid_knife_defend=actid_knife_attack+1function add_to_binder(npc,ini,scheme,section,storage)if not knife_sets.inited theninit()endlocal manager = npc:motivation_action_manager()if not (knife_sets.enabled and not knife_sets.forbiddens.factions[npc:character_community()] and knife_sets.ranks[ranks.get_obj_rank_name(npc)] and not knife_sets.forbiddens.npcs[npc:name()]) thenmanager:add_evaluator(evid_knife_attack,property_evaluator_const(false))returnendmanager:add_evaluator(evid_knife_attack,evaluator_knife_attack(npc,"evaluator_knife_attack",storage))local action = action_knife_attack(npc,"knife_attack",storage)action:add_precondition(world_property(stalker_ids.property_alive,true))action:add_precondition(world_property(xr_evaluators_id.sidor_wounded_base,false))-- action:add_precondition(world_property(xr_evaluators_id.state_mgr+1,true))if rx_gl thenaction:add_precondition(world_property(rx_gl.evid_gl_fire,false))endif rx_bandage thenaction:add_precondition(world_property(rx_bandage.evid_bandage,false))endaction:add_precondition(world_property(evid_knife_attack,true))action:add_effect(world_property(evid_knife_attack,false))manager:add_action(actid_knife_attack,action)for i,id in ipairs({stalker_ids.action_combat_planner,stalker_ids.action_danger_planner,xr_actions_id.stohe_meet_base+1}) doaction = manager:action(id)action:add_precondition(world_property(evid_knife_attack,false))endendfunction set_scheme(npc,ini,scheme,section)local st = xr_logic.assign_storage_and_bind(npc,ini,scheme,section)endfunction disable_scheme(npc,scheme)local st = db.storage[npc:id()][scheme]if st thenst.enabled = falseendend ltx-фаил ;-------------------------------------- ; Модуль knife; Rulix aka Bak;--------------------------------------[main]enabled = truecheck_period = 1001 ;мс ; время между проверкамиforbidden_weapons = none ; запрещенное к использованию оружиеforbidden_factions = zombiedforbidden_npcs = nonefire_dist = 1.5[novice]rate = 0.6 ; ударов в секунду[experienced]rate = 1.1[veteran]rate = 1.3[master]rate = 2;---------------------------------------[stalker]rate_add = 0courage = 0.9attack_wounded = 0.1mutant_hunt = true[bandit]rate_add = 0.1courage = 0.7attack_wounded = 0.2mutant_hunt = false[freedom]rate_add = 0.3courage = 1.4attack_wounded = 0.2mutant_hunt = true[dolg]rate_add = 0courage = 1attack_wounded = 0mutant_hunt = true[killer]rate_add = 0.2courage = 0.8attack_wounded = 0mutant_hunt = true[military]rate_add = 0courage = 0.6attack_wounded = 0mutant_hunt = false[ecolog]rate_add = 0courage = 0.1attack_wounded = 0mutant_hunt = false[monolith]rate_add = 0courage = 1.5attack_wounded = 0.05mutant_hunt = false Скрин Изменено 25 Октября 2015 пользователем Gaz24 Поделиться этим сообщением Ссылка на сообщение