Это популярное сообщение. Dennis_Chikin 3 658 Опубликовано 16 Мая 2014 Это популярное сообщение. Поделиться Опубликовано 16 Мая 2014 Ковыряемся в файлах ТЧ Прежде чем писать в тему - внимательно читаем первый пост, и пользуемся поиском. Возможно, ответ на Ваш вопрос уже есть. Касательно телепатии: если Вы передаете Ваши файлы телепатическим путем - ответы будут передаваться тоже телепатически. Если Вы предлагаете угадать, отчего у Вас в подвале происходит странный стук - ответ будет передан стуком. 4 8 6 12 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 (изменено) Daniar299, как это не изменилось, т.е везде стоит last_day? а лог Expression : no_assert Function : CIni_IdToIndex<1,struct COMMUNITY_DATA,class shared_str,int,class CHARACTER_COMMUNITY>::GetById File : e:\stalker\patch_1_0004\xr_3da\xrgame\ini_id_loader.h Line : 134 Description : item not found, id Arguments : last day и неплохо бы, чтобы ты под спойлером выложил все что делал. Изменено 19 Июля 2012 пользователем Вампир35 Ссылка на комментарий
Daniar299 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Вампир35, Да лог тот же вот что я делал:: [game_relations] ;реальное разделение на группы репутаций на шкалы rating = novice, 300, experienced, 600, veteran, 900, master monster_rating = weak, 400, normal, 800, strong reputation = terrible, -1000, very_bad, -150, bad, -50, neutral, 50, good, 150, very_good, 1000, excellent ;шкалы для вывода названий вместо чисел ;рейтингов, репутаций и благосклонности в интерфейсе rating_names = novice, 300, experienced, 600, veteran, 900, master reputation_names = terrible, -1000, very_bad, -150, bad, -50, neutral, 50, good, 150, very_good, 1000, excellent goodwill_names = enemy, -150, indifferent, 400, friendly ;пороговые значения для отношения персонажей attitude_neutal_threshold = -150 ;когда attitude меньше значения, то выставляется ALife::eRelationEnemy attitude_friend_threshold = 400 ;когда attitude меньше значения, то выставляется ALife::eRelationNeutral, иначе ALife::eRelationFriend ;константы, которые присвоят скриптовые функции set_relation для personal goodwill goodwill_enemy = -1000 goodwill_neutal = 0 goodwill_friend = 1000 ;названия группировок communities = actor, 0, actor_dolg, 1, actor_freedom, 2, stalker, 5, monolith, 6, military, 7, killer, 8, ecolog, 9, dolg, 10, freedom, 11, bandit, 12, zombied, 13, stranger, 14, trader, 15, arena_enemy, 16, Last_Day, 18, actor_Last_Day, 19, ; отношение персонажа к актеру (или другому NPC) вычисляется по формуле ; attitude = personal_goodwill + //личное отношение персонажа к актеру (если раньше не встречались, то 0) ; community_goodwill + //отношение группировки персонажа лично к актеру (если раньше контактов не было, то 0) ; community_to_community + //отношение группировки персонажа к группировке актера из [communities_relations] ; reputation_goodwill + //отношение репутации персонажа к репутации актера из [reputation_relations] ; rank_goodwill //отношение ранга персонажа к рангу актера из [rank_relations] [communities_relations] ; |actor |act_dol|act_fre|stalker|monolit|militar|killer |ecolog |dolg |freedom|bandit |zombied|strange|trader |arena_enemy| Last_Day | actor_Last_Day| ;=============================================================================== ================================================== actor = 0, 0, 0, 50, -1000, -750, -1250, 0, 0, 0, -350, -2000, 0, 0, -1250 actor_dolg = 0, 0, 0, 0, -2000, -650, -1200, 500, 250, -1250, -1000, -2000, 0, 0, -1250 actor_freedom = 0, 0, 0, -80, -1500, -1500, -750, -100, -1250, 150, -150, -2000, 0, 0, -1250 stalker = 50, 0, -80, 40, -1000, -1250, -1500, 0, 0, 0, -250, -2000, 0, 0, -1250 monolith = -1000, -2000, -1500, -1000, 400, -2000, -500, -750, -2000, -1500, -1250, 150, -1250, 0, -1250 military = -750, -650, -1500, -1250, -2000, 700, -1250, 40, -650, -1500, -2000, -2000, -100, 0, -1250 killer = -1250, -1250, -650, -1500, -500, -1250, 150, -1250, -1500, -650, -500, -2000, -1250, 0, -1250 ecolog = 0, 500, -100, 0, -650, 40, -1500, 1250, 500, -100, -1000, -2000, 0, 0, 0 dolg = 0, 250, -1250, 0, -2000, -650, -1500, 500, 650, -1500, -1250, -2000, 0, 0, 0 freedom = 0, -1250, 150, 0, -1500, -1500, -650, -100, -1250, 150, -150, -2000, 0, 0, 0 bandit = -350, -1000, -150, -250, -1250, -2000, -500, -1000, -1250, -150, 40, -2000, -1250, 0, -1250 zombied = -2000, -2000, -2000, -2000, 150, -2000, -2000, -2000, -2000, -2000, -2000, 250, -1250, 0, -1250 stranger = 0, 0, 0, 0, -250, -100, -650, 0, 0, 0, -150, -1250, 0, 0, 0 trader = 0, 0, -40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 arena_enemy = -1000, -1250, -1250, -1000, -1250, -1250, -1250, 0, -650, -1250, -1250, 0, 0, 0, 0 Last_Day = 0, 0, 0, 0, -5000, -5000, -5000, 0, 0, 0, -5000, -5000, 0, 0, -5000, 0 actor_Last_Day = 0, 0, 0, 0, -5000, -5000, -5000, 0, 0, 0, -5000, -5000, 0, 0, -5000, 0, 600, 600 [rank_relations] ; novice, experienced, veteran, master ;================================================================ novice = 70, 20, 0, 0 experienced = 20, 70, 20, 0 veteran = 0, 20, 70, 20 master = 0, 0, 20, 70 [reputation_relations] ; terrible, very_bad, bad, neutral, good, very_good, excellent ;================================================================ terrible = -250, -100, -50, -20, 0, 0, 0 very_bad = -100, -50, -20, 0, 0, 0, 0 bad = -50, -20, 0, 0, 0, 0, 0 neutral = -20, 0, 0, 0, 0, 0, 50 good = 0, 0, 0, 0, 0, 50, 100 very_good = 0, 0, 0, 0, 50, 100, 200 excellent = 0, 0, 0, 50, 100, 200, 350 ; ; очки рейтинга и репутации начисляемые за определенные действия ; ;коэффициенты "сочувствия" группировок ;после воздействия на одного из членов группировки ;goodwill его распространится на остальных членов группировки ;с определенным коэффициентом [communities_sympathy] actor = 0.0 actor_dolg = 0.0 actor_freedom = 0.0 stalker = 0.0 monolith = 0.2 military = 0.2 killer = 0.2 ecolog = 0.4 dolg = 0.2 freedom = 0.2 bandit = 0.1 zombied = 0.0 trader = 0.2 stranger = 0.0 arena_enemy = 0.0 Last_Day = 0.0 actor_Last_Day = 0.0 ; ;очки рейтинга, получаемые за убийство персонажа ;с определенным статусом [rank_kill_points] novice = 0 experienced = 0 veteran = 0 master = 0 --[[------------------------------------------------------------------------------------------------------------------ Respawner. Схема обновления популяции всего всего всего в симуляции. by Stohe (Диденко Руслан) --------------------------------------------------------------------------------------------------------------------]] --function printf() --end local section_name = "respawn" local i,k,v = 0,0,0 -- Таблица ограничений на спаун: всего в симуляции не должно быть больше, чем указано. local simMaxCount = { stalker_novice = 26, stalker_regular = 24, stalker_veteran = 22, stalker_master = 10, monolith_novice = 2, monolith_regular = 15, monolith_veteran = 17, monolith_master = 15, military_novice = 2, military_regular = 16, military_veteran = 11, military_master = 2, killer_novice = 2, killer_regular = 15, killer_veteran = 13, killer_master = 10, ecolog_novice = 1, ecolog_regular = 1, ecolog_veteran = 1, ecolog_master = 1, dolg_novice = 2, dolg_regular = 17, dolg_veteran = 18, dolg_master = 8, freedom_novice = 25, freedom_regular = 10, freedom_veteran = 13, freedom_master = 10, bandit_novice = 15, bandit_regular = 20, bandit_veteran = 9, bandit_master = 5, zombied_novice = 10, zombied_regular = 7, zombied_veteran = 5, zombied_master = 5, Last_Day_novice = 20, Last_Day_regular = 20, Last_Day_veteran = 20, Last_Day_master = 6, local killCountProps = { neutral_novice = 1, neutral_experienced = 2, neutral_veteran = 3, neutral_master = 4, monolith_novice = 1, monolith_experienced = 2, monolith_veteran = 3, monolith_master = 4, military_novice = 1, military_experienced = 2, military_veteran = 3, military_master = 4, killer_novice = 1, killer_experienced = 2, killer_veteran = 3, killer_master = 4, ecolog_novice = 1, ecolog_experienced = 2, ecolog_veteran = 3, ecolog_master = 4, dolg_novice = 1, dolg_experienced = 2, dolg_veteran = 3, dolg_master = 4, freedom_novice = 1, freedom_experienced = 2, freedom_veteran = 3, freedom_master = 4, bandit_novice = 1, bandit_experienced = 2, bandit_veteran = 3, bandit_master = 4, zombied_novice = 1, zombied_experienced = 2, zombied_veteran = 3, zombied_master = 4, Last_Day_novice = 1, Last_Day_experienced = 2, Last_Day_veteran = 3, Last_Day_master = 4, tushkano_weak = 1, flesh_weak = 1, flesh_normal = 2, flesh_strong = 3, boar_weak = 1, boar_normal = 2, boar_strong = 3, cat_weak = 1, burer_weak = 1, burer_normal = 2, burer_strong = 3, fracture_weak = 1, fracture_normal = 2, fracture_strong = 3, chimera_weak = 1, chimera_normal = 2, chimera_strong = 3, zombie_weak = 1, zombie_normal = 2, zombie_strong = 3, dog_weak = 1, dog_normal = 2, dog_strong = 3, pseudodog_weak = 1, pseudodog_normal = 2, pseudodog_strong = 3, psy_dog_weak = 1, psy_dog_normal = 2, psy_dog_strong = 3, snork_weak = 2, snork_normal = 3, snork_strong = 4, poltergeist_weak = 2, pseudo_gigant_weak = 4, controller_weak = 4, bloodsucker_weak = 1, bloodsucker_normal = 2, bloodsucker_strong = 3 } local sect_alias = { tushkano_normal = "tushkano_weak", tushkano_strong = "tushkano_weak", burer_normal = "burer_weak", burer_strong = "burer_weak", fracture_normal = "fracture_weak", fracture_strong = "fracture_weak", cat_normal = "cat_weak", cat_strong = "cat_weak", chimera_normal = "fracture_weak", chimera_strong = "fracture_weak", poltergeist_normal = "poltergeist_weak", poltergeist_strong = "poltergeist_weak", pseudo_gigant_normal = "pseudo_gigant_weak", pseudo_gigant_strong = "pseudo_gigant_weak", controller_normal = "controller_weak", controller_strong = "controller_weak", --[[ -- алиасы не нужны psy_dog_weak = "psy_dog", psy_dog_normal = "psy_dog", psy_dog_strong = "psy_dog", ]] zombie_trup = "zombie_weak", zombie_trup2 = "zombie_weak" } monster_classes = { [clsid.tushkano_s ] = "tushkano", [clsid.flesh_s ] = "flesh", [clsid.boar_s ] = "boar", [clsid.cat_s ] = "cat", [clsid.zombie_s ] = "zombie", [clsid.burer_s ] = "burer", [clsid.fracture_s ] = "fracture", [clsid.chimera_s ] = "chimera", [clsid.dog_s ] = "dog", [clsid.pseudodog_s ] = "pseudodog", [clsid.psy_dog_s ] = "psy_dog", [clsid.psy_dog_phantom_s] = "psy_dog_phantom", [clsid.snork_s ] = "snork", [clsid.poltergeist_s ] = "poltergeist", [clsid.gigant_s ] = "pseudo_gigant", [clsid.controller_s ] = "controller", [clsid.bloodsucker_s ] = "bloodsucker" } function addKillCount(npc) if(npc) then local props, sect = getNpcType(npc) if (props == nil or sect == nil) then return end local sect_name if sect_alias[sect] ~= nil then sect_name = sect_alias[sect] else sect_name = sect end if killCountProps[sect_name] == nil then print_table(sect_alias) abort("Statistic ERROR: required section [%s] not present, based [%s]", tostring(sect_name), tostring(sect)) end actor_stats.add_points(props, sect_name, 1, killCountProps[sect_name]) db.actor:set_character_rank(db.actor:character_rank() + killCountProps[sect_name]) end end function getNpcType(npc) if npc == nil then return nil end if IsStalker(npc) then local community = "neutral" if npc:character_community() == "monolith" then community = "monolith" elseif npc:character_community() == "military" then community = "military" elseif npc:character_community() == "killer" then community = "killer" elseif npc:character_community() == "ecolog" then community = "ecolog" elseif npc:character_community() == "dolg" then community = "dolg" elseif npc:character_community() == "freedom" then community = "freedom" elseif npc:character_community() == "bandit" then community = "bandit" elseif npc:character_community() == "zombied" then community = "zombied" elseif npc:character_community() == "Last_Day" then community = "Last_Day" end function init_drop_settings() local community_list = { "stalker", "dolg", "freedom", "bandit", "military", "zombied", "ecolog", "killer", "monolith", "arena_enemy", "actor_dolg", "Last_Day", "actor_Last_Day" } <string id="Last_Day"> <text>"Последний день"</text> </string> Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 (изменено) Daniar299, во-первых зачем тебе группировка actor_last_day? При вступлении просто давай гг группировку last_day, раз лог тот же, посмотри, кому ты прописывал эту группировку, правильно ли там написано? Изменено 19 Июля 2012 пользователем Вампир35 Ссылка на комментарий
Starter 238 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 (изменено) Morder07, Это не скрипт а логика. gamedata\config\scripts\gar_dm_bandit1.ltx, gar_dm_bandit2.ltx, gar_dm_bandit3.ltx, gar_dm_novice.ltx. --- Подскажите можно ли заспавнить свет или лампочку и как? Просто есть помещение которое необходимо осветить (типа люстры на потолке). Изменено 19 Июля 2012 пользователем Starter ЯДиск папка с крутым схроном! Ссылка на комментарий
Daniar299 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Вампир35, исправил название группировки у НПС которому её дал появилось так: Expression : no_assert Function : CIni_IdToIndex<1,struct COMMUNITY_DATA,class shared_str,int,class CHARACTER_COMMUNITY>::GetById File : e:\stalker\patch_1_0004\xr_3da\xrgame\ini_id_loader.h Line : 134 Description : item not found, id Arguments : last_day Добавлено через 5 мин.: Как я понел он не может найти ид группировки, но как его прописать??? Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 (изменено) [game_relations] ;реальное разделение на группы репутаций на шкалы rating = novice, 300, experienced, 600, veteran, 900, master monster_rating = weak, 400, normal, 800, strong reputation = terrible, -1000, very_bad, -150, bad, -50, neutral, 50, good, 150, very_good, 1000, excellent ;шкалы для вывода названий вместо чисел ;рейтингов, репутаций и благосклонности в интерфейсе rating_names = novice, 300, experienced, 600, veteran, 900, master reputation_names = terrible, -1000, very_bad, -150, bad, -50, neutral, 50, good, 150, very_good, 1000, excellent goodwill_names = enemy, -400, indifferent, 500, friendly ;пороговые значения для отношения персонажей attitude_neutal_threshold = -400;когда attitude меньше значения, то выставляется ALife::eRelationEnemy attitude_friend_threshold = 500;когда attitude меньше значения, то выставляется ALife::eRelationNeutral, иначе ALife::eRelationFriend ;константы, которые присвоят скриптовые функции set_relation для personal goodwill goodwill_enemy = -1000 goodwill_neutal = 0 goodwill_friend = 1000 ;названия группировок communities = actor, 0, actor_dolg, 1, actor_freedom, 2, stalker, 5, monolith, 6, military, 7, killer, 8, ecolog, 9, dolg, 10, freedom, 11, bandit, 12, zombied, 13, stranger, 14, trader, 15, arena_enemy, 16, last_day, 17 ; отношение персонажа к актеру (или другому NPC) вычисляется по формуле ; attitude = personal_goodwill + //личное отношение персонажа к актеру (если раньше не встречались, то 0) ; community_goodwill + //отношение группировки персонажа лично к актеру (если раньше контактов не было, то 0) ; community_to_community + //отношение группировки персонажа к группировке актера из [communities_relations] ; reputation_goodwill + //отношение репутации персонажа к репутации актера из [reputation_relations] ; rank_goodwill //отношение ранга персонажа к рангу актера из [rank_relations] [communities_relations] ; |actor |act_dol|act_fre|stalker|monolit|militar|killer |ecolog |dolg |freedom|bandit |zombied|strange|trader |arena_enemy|last_day| ;=============================================================================== ================================================== actor = 0, 0, 0, 0, -5000, -5000, -5000, 0, 0, 0, -5000, -5000, 0, 0, -5000,0 actor_dolg = 0, 0, 0, 0, -5000, -500, -5000, 5000, 600, -5000, -5000, -5000, 0, 0, -5000,0 actor_freedom = 0, 0, 0, 0, -5000, -5000, -5000, -1500, -5000, 5000, 0, -5000, 0, 0, -5000,0 stalker = 0, 0, 0, 0, -5000, -5000, -5000, 0, 0, 0, -5000, -5000, 0, 0, -5000,0 monolith = -5000, -5000, -5000, -5000, 5000, -5000, -5000, -5000, -5000, -5000, 5000, 5000, -5000, 0, -5000,0 military = -5000, -5000, -5000, -5000, -5000, 5000, -5000, 0, -5000, -5000, -5000, -5000, 0, 0, -5000 killer = -5000, -5000, 0, -5000, -5000, -5000, 5000, -5000, -5000, -5000, 0, -5000, -5000, 0, -5000,0 ecolog = 0, 600, -5000, 0, -5000, 1000, -5000, 5000, 500, -5000, -500, -5000, 0, 0, 0,0 dolg = 0, 600, -5000, 0, -5000, -500, -5000, 5000, 5000, -5000, -5000, -5000, 0, 0, 0,0 freedom = 0, -5000, 600, 0, -5000, -5000, -5000, -1500, -5000, 5000, 0, -5000, 0, 0, 0,0 bandit = -5000, -5000, 0, -5000, -5000, -500, 0, -5000, -5000, 0, 0, -5000, -5000, 0, -5000,0 zombied = -5000, -5000, -5000, -5000, 5000, -5000, -5000, -5000, -5000, -5000, -5000, 5000, -5000, 0, -5000,0 stranger = 0, 0, 0, 0, -5000, -5000, -5000, 0, 0, 0, -500, -5000, 0, 0, 0,0 trader = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0 arena_enemy = -5000, -5000, -5000, -5000, -5000, -5000, 0, 0, 0, -5000, -5000, 0, 0, 0, 0,0 last_day = -5000, -5000, -5000, -5000, 5000, -5000, -5000, -5000, -5000, -5000, 5000, 5000, -5000, 0, -5000,0 [rank_relations] ; novice, experienced, veteran, master ;================================================================ novice = 0, 0, 0, 0 experienced = 0, 0, 0, 0 veteran = 0, 0, 0, 0 master = 0, 0, 0, 0 [reputation_relations] ; terrible, very_bad, bad, neutral, good, very_good, excellent ;================================================================ terrible = 0, 0, 0, 0, 0, 0, 0 very_bad = 0, 0, 0, 0, 0, 0, 0 bad = 0, 0, 0, 0, 0, 0, 0 neutral = 0, 0, 0, 0, 0, 0, 0 good = 0, 0, 0, 0, 0, 0, 0 very_good = 0, 0, 0, 0, 0, 0, 0 excellent = 0, 0, 0, 0, 0, 0, 0 ; ; очки рейтинга и репутации начисляемые за определенные действия ; ;коэффициенты "сочувствия" группировок ;после воздействия на одного из членов группировки ;goodwill его распространится на остальных членов группировки ;с определенным коэффициентом [communities_sympathy] actor = 0.0 actor_dolg = 0.0 actor_freedom = 0.0 stalker = 0.0 monolith = 0.0 military = 0.0 killer = 0.0 ecolog = 0.0 dolg = 0.1 freedom = 0.1 bandit = 0.0 zombied = 0.0 trader = 0.0 stranger = 0.0 arena_enemy = 0.0 last_day = 0.0 ; ;очки рейтинга, получаемые за убийство персонажа ;с определенным статусом [rank_kill_points] novice = 0 experienced = 0 veteran = 0 master = 0 ;очки рейтинга, репутации и доброжелательности начисляемые ;в зависимости от совершенного действия [action_points] personal_goodwill_limits = -1000, 1000 community_goodwill_limits = -3000, 1000 ;------------------------------------------------------- free_friend_attack_goodwill = -2500 free_neutral_attack_goodwill = -1000 free_enemy_attack_goodwill = 0 danger_friend_attack_goodwill = -200 danger_neutral_attack_goodwill = -200 danger_enemy_attack_goodwill = 0 free_friend_attack_reputation = -20 free_neutral_attack_reputation = -10 free_enemy_attack_reputation = 0 danger_friend_attack_reputation = 0 danger_neutral_attack_reputation = 0 danger_enemy_attack_reputation = 0 ;-------------------------------------------------- ;(с) мин. время через которое снова будет зарегистрировано ;сообщение об атаке на персонажа, и соответственно вычтеся attack_goodwill и attack_reputation ;(работает аналогично и при помощи другим персонажам в бою) min_attack_delta_time = 3 friend_kill_goodwill = -1000 neutral_kill_goodwill = -1000 enemy_kill_goodwill = 0 community_member_kill_goodwill = -1000 ;убийство члена группировки отражается на отношении ;группировки (умножается на communities_sympathy) friend_kill_reputation = -40 neutral_kill_reputation = -15 enemy_kill_reputation = 0 ; ; помощь актера персонажу во время боя ; fight_remember_time = 10;(c) время которое про драку будет помнить реестр friend_fight_help_goodwill = 200 neutral_fight_help_goodwill = 200 enemy_fight_help_goodwill = 0 friend_fight_help_reputation = 10 neutral_fight_help_reputation = 10 enemy_fight_help_reputation = 0 ;свойства, которые изменяются у сталкеров в ;зависимости от их ранга ;коэффициенты линейно интерполируются для рангов от 0 (novice) до 100 (experienced) [ranks_properties] immunities_novice_k = 1.0 immunities_experienced_k = 1.0 visibility_novice_k = 1 visibility_experienced_k = 1 dispersion_novice_k = 1.0 dispersion_experienced_k = 0.1 ; диапазон изменения рангов при регистрации в новом смарт террейне [smart_terrain_rank_change] min = 1 max = 30 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; for monsters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [monster_communities] ;номера team которые присваиваются соответствующим видам ;255 - команда не задается communities = actor, 255, human, 255, arena_monstr, 39, boar, 40, bloodsucker, 41, flesh, 42, dog, 43, pseudodog, 44, cat, 45, chimera, 46, giant, 47, zombie, 48, burer, 49, controller, 50, poltergeist, 51, snork, 52, fracture, 53, bird, 54, rat, 55, tushkano, 56 [monster_relations] ; [1] друг, [0] нейтрал, [-1] враг, [-2] злейший враг ; actor,human,arena_monstr, boar, bloodsucker, flesh, dog, pseudodog, cat, chimera, giant, zombie, burer, controller, poltergeist, snork, fracture, bird, rat, tushkano ;=============================================================================== ================================================================================ = ========== actor = 1, 1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1 human = 0 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1 arena_monstr= -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 boar = -2, -2, 0, 1, -1, 0, -1, -1, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0 bloodsucker = -2, -2, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 flesh = -2, -1, 0, 0, -1, 1, -1, -1, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0 dog = -2, -1, 0, -1, 0, -1, 1, 0, 0, 0, -1, 0, -1, -1, -1, 0, 0, 0, 0, 0 pseudodog = -2, -1, 0, -1, 0, -1, 0, 1, 0, 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0 cat = -2, -1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 chimera = -2, -1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 giant = -2, -1, 0, -1, 0, -1, -1, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 zombie = -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 burer = -2, -2, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 controller = -2, -2, 0, -1, 0, -1, -1, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0 poltergeist = -2, -1, 0, -1, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 snork = -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0 fracture = -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 bird = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 rat = -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 tushkano = -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 [stalker];Указывается вероятность заспаунить или нет ;Артефакты af_medusa = 0.015 af_cristall_flower = 0.01 af_night_star = 0.005 af_vyvert = 0.015 af_gravi = 0.01 af_gold_fish = 0.005 af_blood = 0.015 af_mincer_meat = 0.01 af_soul = 0.005 af_electra_sparkler = 0.015 af_electra_flash = 0.01 af_electra_moonlight = 0.005 af_rusty_thorn = 0.015 af_rusty_kristall = 0.01 af_rusty_sea-urchin = 0.005 af_ameba_slime = 0.015 af_ameba_slug = 0.01 af_ameba_mica = 0.005 af_drops = 0.015 af_fireball = 0.01 af_cristall = 0.005 af_dummy_glassbeads = 0.005 af_dummy_pellicle = 0.005 af_dummy_battery = 0.005 af_dummy_dummy = 0.005 af_dummy_spring = 0.005 af_fuzz_kolobok = 0.005 ;Аммуниция ammo_9x18_fmj = 1 ammo_9x18_pmm = 1 ammo_9x19_pbp = 1 ammo_9x19_fmj = 1 ammo_11.43x23_hydro = 1 ammo_11.43x23_fmj = 1 ammo_12x70_buck = 1 ammo_12x76_dart = 1 ammo_12x76_zhekan = 1 ammo_5.45x39_ap = 1 ammo_5.45x39_fmj = 1 ammo_9x39_sp5 = 1 ammo_9x39_ap = 1 ammo_9x39_pab9 = 1 ammo_5.56x45_ss190 = 1 ammo_5.56x45_ap = 1 ammo_7.62x54_7h14 = 1 ammo_7.62x54_7h1 = 1 ammo_7.62x54_ap = 1 ammo_gauss = 1 ammo_og-7b = 1 ammo_vog-25p = 0.1 ammo_vog-25 = 0.1 grenade_f1 = 0.1 grenade_rgd5 = 0.1 ammo_m209 = 0.1 ;Медикаменты bandage = 0.4 medkit = 0.2 medkit_army = 0 medkit_scientic = 0.05 antirad = 0.2 ;Еда bread = 0.2 kolbasa = 0.2 conserva = 0.1 vodka = 0.1 energy_drink = 0.1 [bandit]:stalker [killer]:stalker ;Еда bread = 0 kolbasa = 0 vodka = 0 energy_drink = 0.3 [ecolog]:stalker ;Еда bread = 0 kolbasa = 0 conserva = 0 vodka = 0 energy_drink = 0 medkit = 0 medkit_scientic = 0.2 antirad = 0.3 [military]:stalker af_medusa = 0 af_cristall_flower = 0 af_night_star = 0 af_vyvert = 0 af_gravi = 0 af_gold_fish = 0 af_blood = 0 af_mincer_meat = 0 af_soul = 0 af_electra_sparkler = 0 af_electra_flash = 0 af_electra_moonlight = 0 af_rusty_thorn = 0 af_rusty_kristall = 0 af_rusty_sea-urchin = 0 af_ameba_slime = 0 af_ameba_slug = 0 af_ameba_mica = 0 af_drops = 0 af_fireball = 0 af_cristall = 0 af_dummy_glassbeads = 0 af_dummy_pellicle = 0 af_dummy_battery = 0 af_dummy_dummy = 0 af_dummy_spring = 0 af_fuzz_kolobok = 0 ;Медикаменты bandage = 0.4 antirad = 0.3 medkit = 0 medkit_scientic = 0 medkit_army = 0.2 ;Еда bread = 0.2 kolbasa = 0 conserva = 0.3 vodka = 0 energy_drink = 0 [dolg]:stalker ;Медикаменты medkit_army = 0.2 medkit_scientic = 0.2 [freedom]:stalker ;Еда vodka = 0.5 [zombied]:stalker af_medusa = 0 af_cristall_flower = 0 af_night_star = 0 af_vyvert = 0 af_gravi = 0 af_gold_fish = 0 af_blood = 0 af_mincer_meat = 0 af_soul = 0 af_electra_sparkler = 0 af_electra_flash = 0 af_electra_moonlight = 0 af_rusty_thorn = 0 af_rusty_kristall = 0 af_rusty_sea-urchin = 0 af_ameba_slime = 0 af_ameba_slug = 0 af_ameba_mica = 0 af_drops = 0 af_fireball = 0 af_cristall = 0 af_dummy_glassbeads = 0 af_dummy_pellicle = 0 af_dummy_battery = 0 af_dummy_dummy = 0 af_dummy_spring = 0 af_fuzz_kolobok = 0 ;Еда bread = 0 kolbasa = 0 conserva = 0 vodka = 0 energy_drink = 0 [monolith]:stalker ;Артефакты af_medusa = 0 af_cristall_flower = 0 af_night_star = 0 af_vyvert = 0 af_gravi = 0 af_gold_fish = 0 af_blood = 0 af_mincer_meat = 0 af_soul = 0 af_electra_sparkler = 0 af_electra_flash = 0 af_electra_moonlight = 0 af_rusty_thorn = 0 af_rusty_kristall = 0 af_rusty_sea-urchin = 0 af_ameba_slime = 0 af_ameba_slug = 0 af_ameba_mica = 0 af_drops = 0 af_fireball = 0 af_cristall = 0 af_dummy_glassbeads = 0 af_dummy_pellicle = 0 af_dummy_battery = 0 af_dummy_dummy = 0 af_dummy_spring = 0 af_fuzz_kolobok = 0 ;Еда vodka = 0 [arena_enemy] [actor_dolg] [last_day]:stalker ;Артефакты af_medusa = 0.016 af_dummy_glassbeads = 0.004 --[[------------------------------------------------------------------------------------------------------------------ Respawner. Схема обновления популяции всего всего всего в симуляции. by Stohe (Диденко Руслан) --------------------------------------------------------------------------------------------------------------------]] --function printf() --end local section_name = "respawn" local i,k,v = 0,0,0 -- Таблица ограничений на спаун: всего в симуляции не должно быть больше, чем указано. local simMaxCount = { stalker_novice = 43, stalker_regular = 48, stalker_veteran = 43, stalker_master = 20, monolith_novice = 0, monolith_regular = 30, monolith_veteran = 35, monolith_master = 30, military_novice = 0, military_regular = 32, military_veteran = 22, military_master = 5, killer_novice = 0, killer_regular = 18, killer_veteran = 17, killer_master = 10, ecolog_novice = 1, ecolog_regular = 1, ecolog_veteran = 1, ecolog_master = 1, dolg_novice = 0, dolg_regular = 33, dolg_veteran = 36, dolg_master = 17, freedom_novice = 50, freedom_regular = 20, freedom_veteran = 26, freedom_master = 21, bandit_novice = 40, bandit_regular = 50, bandit_veteran = 18, bandit_master = 10, zombied_novice = 20, zombied_regular = 15, zombied_veteran = 10, zombied_master = 10, last_day_novice = 20, last_day_regular = 15, last_day_veteran = 10, last_day_master = 10, rat_weak = 0, tushkano_weak = 150, flesh_weak = 14, flesh_normal = 38, flesh_strong = 22, boar_weak = 52, boar_normal = 38, boar_strong = 27, dog_weak = 53, dog_normal = 126, dog_strong = 130, pseudodog_weak = 59, pseudodog_normal = 80, pseudodog_strong = 60, psy_dog_weak = 15, psy_dog_normal = 15, psy_dog_strong = 15, zombie_weak = 61, zombie_normal = 50, zombie_strong = 35, snork_weak = 50, snork_normal = 61, snork_strong = 15, poltergeist_weak = 10, pseudo_gigant_weak = 23, controller_weak = 18, burer_weak = 20, bloodsucker_weak = 7, bloodsucker_normal = 40, bloodsucker_strong = 15 } local idle_spawn_preset = { seldom = 60*60, medium = 60*60, often = 60*60 } -- Список респавнеров, для сбора статистики local respawners = {} local respawners_by_parent = {} ---------------------------------------------------------------------------------------------------------------------- -- Разные полезные функции ---------------------------------------------------------------------------------------------------------------------- function r_bool( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_bool( section, line ) else return default end end function r_str( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_string( section, line ) else return default end end function r_num( spawn_ini, section, line, default ) if spawn_ini:line_exist( section, line ) then return spawn_ini:r_float( section, line ) else return default end end function r_2nums( spawn_ini, section, line, def1, def2 ) if spawn_ini:line_exist( section, line ) then -- если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini local t = parse_names( spawn_ini:r_string( section, line ) ) local n = table.getn( t ) if n == 0 then return def1, def2 elseif n == 1 then return t[1], def2 else return t[1], t[2] end else return def1, def2 end end function parse_names( s ) local t = {} for name in string.gfind( s, "([%w_%-.\\]+)%p*" ) do table.insert( t, name ) end return t end function r_spawns( spawn_ini, section, line, sectSpawnProps) if spawn_ini:line_exist( section, line ) then --' если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini local t = parse_names( spawn_ini:r_string( section, line ) ) local n = table.getn( t ) local ret_table = {} local k = 1 while k <= n do local spawn = {} spawn.section = t[k] -- Проверяем что это не последняя запись if t[k+1] ~= nil then local p = tonumber(t[k+1]) -- проверяем что вторым числом задана вероятность, а не другая секция спавну if p then -- забиваем число spawn.prob = p k = k + 2 else -- забиваем дефолт 1 spawn.prob = 1 k = k + 1 end else spawn.prob = 1 k = k + 1 end table.insert(ret_table, spawn) -- Вычитываем настройки секций респавна и кешируем их. if sectSpawnProps[spawn.section] == nil then local respawn_ini = system_ini() local community = r_str(respawn_ini, spawn.section, "community", "nil") local rank = r_str(respawn_ini, spawn.section, "spec_rank", "nil") local check = true local custom_data = r_str(respawn_ini, spawn.section, "custom_data") if custom_data ~= nil then local custom_data_ltx = ini_file(custom_data) if custom_data_ltx:section_exist("smart_terrains") then if custom_data_ltx:line_exist("smart_terrains", "none") then if r_str(custom_data_ltx, "smart_terrains", "none") == "true" then check = false end end if custom_data_ltx:line_exist("smart_terrains", "respawn_check") then if r_str(custom_data_ltx, "smart_terrains", "respawn_check") == "false" then check = false end end end end sectSpawnProps[spawn.section] = {community = community, rank = rank, check = check} end end return ret_table end return nil end ---------------------------------------------------------------------------------------------------------------------- -- Серверный объект спавнера ---------------------------------------------------------------------------------------------------------------------- class "se_respawn" ( cse_alife_smart_zone ) function se_respawn:__init( section ) super( section ) self.spawned_obj = {} -- Таблица для кеширования свойств секций респавна. self.sectSpawnProps = {} self.proxy_initialized = false end -- сохранение function se_respawn:STATE_Write( packet ) cse_alife_smart_zone.STATE_Write( self, packet ) local table_size = table.getn(self.spawned_obj) -- printf("SPAWNER SAVE table_size[%d]", table_size) -- print_table(self.spawned_obj) packet:w_u8(table_size) for i=1,table_size do packet:w_u16(self.spawned_obj[i]) end end -- восстановление function se_respawn:STATE_Read( packet, size ) cse_alife_smart_zone.STATE_Read( self, packet, size ) if editor() then return end local table_size = packet:r_u8() for i=1,table_size do table.insert(self.spawned_obj, packet:r_u16()) end -- printf("SPAWNER READ table_size[%d]", table_size) -- print_table(self.spawned_obj) end -- инициализация объекта. -- вызывается симулятором. function se_respawn:on_register() cse_alife_smart_zone.on_register( self ) --printf("RESPAWN: [%s] se_respawn on_register", tostring(self:name())) -- Вычитываем настройки спауна local ini = self:spawn_ini() if not ini:section_exist(section_name) then return end self.respawn_section = r_spawns(ini, section_name, "respawn_section", self.sectSpawnProps) if self.respawn_section == nil then abort("RESPAWN: [%s] field 'respawn_section' doesn't exist.", self:name()) end self.min_count = r_num(ini, section_name, "min_count", 0) self.max_count = r_num(ini, section_name, "max_count", -1) if self.min_count > self.max_count and self.max_count ~= -1 then abort("RESPAWN: [%s] min_count > max_count", self:name()) end --' FOR DEBUG ONLY, please don't forget to delete --'if self.max_count > 0 then --' self.min_count = self.max_count --'end self.max_spawn = r_num(ini, section_name, "max_spawn", 1) self.idle_spawn_min, self.idle_spawn_max = r_2nums(ini, section_name, "idle_spawn") if self.idle_spawn_min == nil then abort("RESPAWN: [%s] field 'idle_spawn' doesn't exist.", self:name()) end if self.idle_spawn_max == nil then self.idle_spawn_max = self.idle_spawn_min end --' Вычитка пресетов if idle_spawn_preset[self.idle_spawn_min] ~= nil then self.idle_spawn_min = idle_spawn_preset[self.idle_spawn_min] else self.idle_spawn_min = tonumber(self.idle_spawn_min) end if idle_spawn_preset[self.idle_spawn_max] ~= nil then self.idle_spawn_max = idle_spawn_preset[self.idle_spawn_max] else self.idle_spawn_max = tonumber(self.idle_spawn_max) end self.str_conditions = r_str(ini, section_name, "conditions", 100) self.conditions = xr_logic.parse_condlist(self, section_name, "conditions", self.str_conditions) self.respawn_radius = r_num(ini, section_name, "respawn_radius", -1) --' Спешкейс, чтобы сохранить совместимость сейвов. if self:name() == "mil_freedom_barier_respawn_1" then self.respawn_radius = -1 end self.parent = r_num(ini, section_name, "parent", nil) self.item_spawn = r_bool(ini, section_name, "item_spawn", false) -- производим первичную инициализацию self.respawn_time = game.CTime() -- Для сбора статистики сохраняем указатель на респавнер respawners[self:name()] = self if self.parent ~= nil then respawners_by_parent[self.parent] = self end --' Отметка респавнера мапспотом (для статистики) sim_statistic.register_respawn(self) end -- Создаем объект function se_respawn:create(prob) if tostring(prob) == "nil" then print_table(self.conditions) abort("RESPAWN[%s]spawn probability doesn't set", tostring(self:name())) prob = 0 end if math.random(100) <= tonumber(prob) then local spawn_section = "" local sum = 0 -- Производим рандомную взвешенную выборку -- с учетом уже заспавленного количества человек. for k,v in pairs(self.respawn_section) do --' local tt = self.sectSpawnProps[v.section] --' local community_rank = tt.community.."_"..tt.rank --' local s_count = simMaxCount[community_rank] --' if s_count == nil then --' s_count = 0 --' end --' if tt.check == false or --' self.item_spawn == true or --' sim_statistic.simNpcCount(tt.community, tt.rank) < s_count --' then sum = sum + v.prob --' end end sum = math.random(0, sum) for k,v in pairs(self.respawn_section) do --' local tt = self.sectSpawnProps[v.section] --' local community_rank = tt.community.."_"..tt.rank --' local s_count = simMaxCount[community_rank] --' if s_count == nil then --' s_count = 0 --' end --' if tt.check == false or --' self.item_spawn == true or --' sim_statistic.simNpcCount(tt.community, tt.rank) < s_count --' then sum = sum - v.prob if sum <= 0 then spawn_section = v.section break end --' end end if spawn_section == "" then -- printf("SPAWNING [%s], CANT SPAWN, SIMULATION POPULATION EXCEED", tostring(self:name())) return false end local parent_id = nil if self.parent ~= nil then local s_obj = alife():story_object(self.parent) if s_obj == nil then abort("SPAWNING [%s], cant find parent with SID [%s]", self:name(), self.parent) return end parent_id = s_obj.id end local obj if parent_id == nil then obj = alife():create(spawn_section, self.position, self.m_level_vertex_id, self.m_game_vertex_id) else obj = alife():create(spawn_section, self.position, self.m_level_vertex_id, self.m_game_vertex_id, parent_id) end local tt = self.sectSpawnProps[spawn_section] -- printf("SPAWN [%s] -> [%s]", tostring(self:name()), obj:name()) if self.item_spawn == false then if tt.check == true then obj:brain():update() local smart_terrain_id = obj:smart_terrain_id() -- printf("SPAWN [%s] move_offline [%s], interactive [%s], smart_terrain_id [%s]", tostring(self:name()), tostring(self:move_offline()), tostring(self:interactive()), smart_terrain_id) if smart_terrain_id ~= 65535 then table.insert(self.spawned_obj ,obj.id) local pos = obj.position -- printf("SPAWNING [%s] -> [%s], position [%s][%s][%s]", tostring(self:name()), spawn_section, pos.x, pos.y, pos.z) local sm_obj = alife():object(smart_terrain_id) printf("SPAWNING for SMART [%s] : [%s] -> [%s]", self:name(), obj:name(), sm_obj:name()) return true else alife():release(obj, true) -- printf("SPAWNING [%s] -> [%s], CANT SPAWN. NO SMART_TERRAIN AVAILABLE!!!", tostring(self:name()), spawn_section) return false end end end table.insert(self.spawned_obj ,obj.id) return true end end -- Попытка спаунить объекты. Анализируется сколько уже заспавнено и выбирается один из механизмов - либо -- мы доспавниваем до минимального количества, либо спавним с заданной вероятностью function se_respawn:spawn() -- printf("RESPAWN: [%s] spawn execute", tostring(self:name())) -- Пробегаемся по списку уже заспавненных объектов и удаляем из них мертвые либо уничтоженные. for k,v in pairs(self.spawned_obj) do local obj = level.object_by_id(v) if obj == nil then obj = alife():object(v) end if obj ~= nil then if (IsStalker(obj) or IsMonster(obj)) and obj:alive() ~= true then table.remove(self.spawned_obj, k) end else table.remove(self.spawned_obj, k) end end if xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions) == "0" then -- printf("SPAWNING [%s], CANT SPAWN. PROBABILITY ZERO!!!", tostring(self:name())) sim_statistic.respawn_enabled(self, false) return end sim_statistic.respawn_enabled(self, true) -- экстренный спаун минимального количества объектов if table.getn(self.spawned_obj) < self.min_count then while table.getn(self.spawned_obj) < self.min_count do if self:create(100) == false then return end end return end -- делаем несколько попыток заспаунить объект. for i=1,self.max_spawn do if self.max_count ~= -1 and table.getn(self.spawned_obj) >= self.max_count then -- printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(self:name())) return end if self:create(xr_logic.pick_section_from_condlist(db.actor_proxy, self, self.conditions)) == false then return end end end --' Удаляем уже заспавненный объект из списка заспавненных --' Используется только для ящиком со шмотками в смарттеррейнах function se_respawn:remove_spawned(id) for k,v in pairs(self.spawned_obj) do if id == v then table.remove(self.spawned_obj, k) end end end -- Обновление респавнера. В зависимости от настроек обновляется либо только в офлайне, либо и там и там. function se_respawn:execute() -- printf("RESPAWN: [%s] se_respawn execute", tostring(self:name())) --' Выходим, если у нас установлен событийный спавн. if self.idle_spawn_min == -1 then return end if self.respawn_time < game.get_game_time() then -- if not self.proxy_initialized then -- db.actor_proxy:init() -- self.proxy_initialized = true -- end local idle_time = game.CTime() idle_time:setHMSms( 0, 0, 0, math.random(self.idle_spawn_min, self.idle_spawn_max)*1000) self.respawn_time = game.get_game_time() + idle_time -- Производим попытку заспаунить объекты self:spawn() -- printf("spawn_count = %s", table.getn(self.spawned_obj)) end end -- Обновление в офлайне function se_respawn:update() cse_alife_smart_zone.update( self ) --'printf("RESPAWN: [%s] se_respawn update_offline", tostring(self:name())) self:execute() end -- Обновление в онлайне function se_respawn:update_online() --'cse_alife_smart_zone.update( self ) --'printf("RESPAWN: [%s] se_respawn update_online", tostring(self:name())) if self.respawn_radius == -1 then sim_statistic.respawn_enabled(self, false) return end if db.actor:position():distance_to (self.position) >= self.respawn_radius then self:execute() else sim_statistic.respawn_enabled(self, false) end end function spawn(name) local spawner = respawners[name] if spawner == nil then return end for i=1,spawner.max_spawn do if spawner.max_count ~= -1 and table.getn(spawner.spawned_obj) >= spawner.max_count then -- printf("SPAWNING [%s], CANT SPAWN. MAX COUNT REACHED!!!", tostring(spawner:name())) return end if spawner:create(xr_logic.pick_section_from_condlist(db.actor_proxy, spawner, spawner.conditions)) == false then return end end end function get_respawner_by_parent(parent_id) return respawners_by_parent[parent_id] end -- Сбор статистики function stats() local total_spawned = 0 local total_avail = 0 local total = 0 printf("***************** RESPAWN STATISTIC *********************") for k,v in pairs(respawners) do local s = xr_logic.pick_section_from_condlist(db.actor_proxy, v, v.conditions) local pops = "DISABLE" if s ~= "nil" and s ~= "0" then pops = table.getn(v.spawned_obj) end local str_pops if v.max_count == pops then str_pops = "FULL "..tostring(pops) else str_pops = tostring(pops) end printf("[%s] spawns [%s] object", tostring(v:name()), str_pops) print_table(v.respawn_section) -- Увеличиваем общие счетчики total = total + v.max_count if pops ~= "DISABLE" then total_avail = total_avail + v.max_count total_spawned = total_spawned + pops end end printf("*** SUMMARY ***") printf(" total = %s", total) printf(" total_avail = %s", total_avail) printf(" total_spawned = %s", total_spawned) printf("***************") end -- Сбор продвинутой статистики статистики по лимитам function lstats() local can_spawn = {} printf("***************** LIMITS STATISTIC *********************") for k,v in pairs(respawners) do -- Запоминаем максимальное количество весов для данного респавнера local wage = 0 for kk,vv in pairs(v.respawn_section) do wage = wage + vv.prob end -- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить. for kk,vv in pairs(v.respawn_section) do local tt = v.sectSpawnProps[vv.section] local community_rank = tt.community.."_"..tt.rank if can_spawn[community_rank] == nil then can_spawn[community_rank] = {community = tt.community, rank = tt.rank} end end end -- Выводим все это в общей статистике local total_max, total_prob, total_current, total_limit = 0,0,0,0 for k,v in pairs(can_spawn) do local cs = sim_statistic.simNpcCount(v.community, v.rank) local gl = simMaxCount[k] if gl == nil then gl = 0 end total_current = total_current + cs total_limit = total_limit + gl printf("%s current=%s limit=%s", k, cs, gl) end printf("TOTAL: current=%s limit=%s", total_current, total_limit) end -- Сбор статистики по ненастроенным объектам function estats() printf("***************** SPAWN ERROR STATISTIC *********************") for k,v in pairs(respawners) do -- Заносим максимальное количество всех типов чуваков, которые данный респавнер может наспаунить. for kk,vv in pairs(v.respawn_section) do local tt = v.sectSpawnProps[vv.section] if tt.community == "nil" or tt.rank == "nil" then printf("respawner [%s]", tostring(v:name())) printf("Section [%s] community[%s] rank [%s]", vv.section, tt.community, tt.rank) end end end end function create_ammo(section, position, lvi, gvi, pid, num) local ini = system_ini() local num_in_box = ini:r_u32(section, "box_size") while num > num_in_box do alife():create_ammo(section, position, lvi, gvi, pid, num_in_box) num = num - num_in_box end alife():create_ammo(section, position, lvi, gvi, pid, num) end --' Ключем является группировка персонажа. Значением является таблица, содержашая имена секций предметов. local item_by_community = {} --' Зависимости в спауне предметов. Предмет спауниться только если есть хотя бы один из зависимых. local item_dependence = {} --' Множители и минимаксы для выпадения вещей в зависимости от уровня local mul_by_level = {} local count_by_level = {} --' Предметы, которые нельзя удалять (квестовые например) 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" , "last_day" } for k,v in pairs(community_list) do --' Необходимо заполнить таблицу item_by_community[v] = {} if death_ini:section_exist(v) then local n = death_ini:line_count(v) local id, value = "", "" for i=0,n-1 do result, id, value = death_ini:r_line(v,i,"","") item_by_community[v][id] = 100*tonumber(value) end end end --' Заполняем таблицу зависимостей local n = death_ini:line_count("item_dependence") local id, value = "", "" for i=0,n-1 do result, id, value = death_ini:r_line("item_dependence",i,"","") item_dependence[id] = {} local vvv = parse_names(value) for k,v in pairs(vvv) do item_dependence[id][v] = true end end --' Множители и минимаксы для выпадения вещей в зависимости от уровня local level_name = level.name() if not death_ini:section_exist(level_name) then level_name = "default" end local n = death_ini:line_count(level_name) local id, value = "", "" for i=0,n-1 do result, id, value = death_ini:r_line(level_name,i,"","") mul_by_level[id] = tonumber(value) end local item_count_section = "item_count_" .. level.get_game_difficulty() local n = death_ini:line_count(item_count_section) for i=0,n-1 do result, id, value = death_ini:r_line(item_count_section,i,"","") --' Нужно распарсить value в два значения local t = parse_nums(value) if t[1] == nil then abort("Error on [death_ini] declaration. Section [%s], line [%s]", item_count_section, tostring(id)) end local min = t[1] local max = t[2] if max == nil then max = min end if mul_by_level[id] == nil then mul_by_level[id] = 0 end min = tonumber(min) * mul_by_level[id] max = tonumber(max) * mul_by_level[id] count_by_level[id] = {min = min, max = max} end --' Предметы, которые нельзя удалять (квестовые например) local n = death_ini:line_count("keep_items") for i=0,n-1 do result, id, value = death_ini:r_line("keep_items",i,"","") if value == "true" then always_keep_item[id] = true end end --' Предметы, относящиеся к патронам. Их надо спаунить другим методом. ammo_sections = {} local n = death_ini:line_count("ammo_sections") local id, value = "", "" for i=0,n-1 do result, id, value = death_ini:r_line("ammo_sections",i,"","") ammo_sections[id] = true end end class "drop_manager" function drop_manager:__init(npc) self.npc = npc end function drop_manager:create_release_item() --' Спрашиваем у серверного объекта генерились ли предметы local se_obj = alife():object(self.npc:id()) if se_obj.death_droped == true then return end se_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") then return end --' Доспавниваем необходимое количество итемов: --' Необходимо составить список объектов которые могут быть заспавнены для персонажа local spawn_items = item_by_community[self.npc:character_community()] for k,v 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) end end end --' Функция вызывается для каждого предмета, если вернет false то предмет удалится. function keep_item(npc, item) local section = item:section() if section == "bolt" then return false end if always_keep_item[section] == true then return true end local item_id = item:id() local item_in_slot = npc:item_in_slot(1) if item_in_slot ~= nil and item_in_slot:id() == item_id then item:unload_magazine() --' Тут надо уменьшить кондишн оружия item:set_condition((math.random(15)+75)/100) return true end item_in_slot = npc:item_in_slot(2) if item_in_slot ~= nil and item_in_slot:id() == item_id then item:unload_magazine() --' Тут надо уменьшить кондишн оружия item:set_condition((math.random(15)+75)/100) return true end alife():release(alife():object(item:id()), true) end --' Функция спавнит необходимое число предметов function create_items(npc, section, number, rnd) --'printf("create %s of %s", tostring(number), tostring(section)) if ammo_sections[section] == true then if number > 0 then se_respawn.create_ammo(section, npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id(), number) end else for i=1,number do --' Проверяем вероятность появить каждый объект в отдельности if math.random(100) <= rnd then alife():create(section, npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()) end end end end --' Функция проверяет есть ли хоть один из зависимых объектов у персонажа function check_item_dependence(npc, section) if item_dependence[section] == nil then return true end local d_flag = true for k,v in pairs(item_dependence[section]) do local obj = npc:object(k) if obj ~= nil and npc:marked_dropped(obj) ~= true then return true end d_flag = false end return d_flag end Все заменил, потому как у тебя слишком странное расстояние между строками в файле game_relations Изменено 19 Июля 2012 пользователем Вампир35 Ссылка на комментарий
Daniar299 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Вампир35, раньше был вылет при начале новой игры, теперь при запуске, появился такой: Expression : fatal error Function : CScriptEngine::lua_error File : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp Line : 73 Description : <no expression> Arguments : LUA error: ...shadow of chernobyl2\gamedata\scripts\amk_mod.script:1731: attempt to call field 'reinit_spawner_params' (a nil value) Пытаюсь в этом файле пытаюсь разобраться, но немогу понять в чём смысл?? Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 (изменено) Starter, конечно можно. [7] ; cse_abstract properties section_name = lights_hanging_lamp name = ds_lights_hanging_lamp position = 114.868431091309,-3.05655956268311,-30.8430423736572 direction = 0.0329925864934921,3.14159250259399,3.14159250259399 version = 118 script_version = 6 ; cse_alife_object properties game_vertex_id = 2909 distance = 0 level_vertex_id = 1268 object_flags = 0xffffffba ; cse_visual properties visual_name = physics\light\new_light\light_galogen_1_glass ; cse_ph_skeleton properties ; cse_alife_object_hanging_lamp properties main_color = 0xffffffff main_brightness = 1 main_range = 10 light_flags = 0x1f lamp_fixed_bones = link health = 100 main_virtual_size = 0.100000001490116 ambient_radius = 10 ambient_power = 0.100000001490116 main_bone = bone_lamp main_cone_angle = 2.09439516067505 glow_radius = 0.699999988079071 Объясняю Кость, которая зафиксирована, чтоб лампа не упала при выстреле lamp_fixed_bones = link Кость от которой идет свет main_bone = bone_lamp Визуал лампы visual_name = physics\light\new_light\light_galogen_1_glass Координаты и прочее вставишь сам Добавлено через 1 мин.: Daniar299, это уже с оригиналом несвязано, к сожалению помочь не могу, скорее всего в затронутых мною скриптах было что-то от амк мода, так что перенеси все что я менял в скриптах в амкашные скрипты. Изменено 19 Июля 2012 пользователем Вампир35 Ссылка на комментарий
Daniar299 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Перенёс, вроде всё работает всё хорошо! Спс! Добавлено через 10 мин.: Ещё такой вопрос, как в энциклопедию ПДА добавить информацию про новую группировку? Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Daniar299, <article id="social_last_day" name="Army" group="Social"> <texture x="768" y="128" width="128" height="128">ui\ui_icons_npc</texture> <text>enc_social_military_army</text> </article> <texture x="768" y="128" width="128" height="128"> здесь указана иконка, по каким она координатам и ее размар. <string id="enc_social_military_army"> <text>Последний день-это........</text> </string> <info_portion id="vidaem_o_last_day"> <article>social_last_day</article> </info_portion> потом выдай в диалоге, или еще где инфопоршень vidaem_o_last_day Ссылка на комментарий
Daniar299 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Как добавить новую иконку НПС??? Прошу объяснить, а то не совсем понимаю что там делать в фотошопе! Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Daniar299, делаешь нужный скрин. Открываешь с помощью программы(я для этих целей использую paint.net) любой файл с иконками нпс, перетаскиваешь скрин туда, подрезаешь, подгоняешь размер, обводишь его инструментом прямоугольное выделение, внизу будут координаты иконки, которые надо перенести в конфиг(справедливо не только для иконок НПС). Ссылка на комментарий
плащ 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 плащ, ну так в чём проблема? 1. Убери все диалоги и задания. Чтобы убрать задание "Убить стрелка" в файле bind_stalker.script найди и закоментируй вот этот код: 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 2. В этом же файле, после закомментированного кода вставь функцию выдачи сообщения на экран, сообщения появится один раз при начале новой игры. вставил получилось что-то типо этого -- 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 <action>start_soobshenie.ваш текст</action> не работает Пытаюсь создать глобальный мод с новым сюжетом,буду рад любой оказанной помощи Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 плащ, надо не так, надо так --[[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]] news_manager.send_tip(db.actor, "твой текст сообщения") Ссылка на комментарий
плащ 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Вампир35, спасибо но у меня еще вопрос как вывести его на экран? Пытаюсь создать глобальный мод с новым сюжетом,буду рад любой оказанной помощи Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 плащ, оно и так выведется, если есть только звук, а тектса нету(только в кпк в истории), такой глюк бывает, пока не нашел как править. Ссылка на комментарий
плащ 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Вампир35, хорошо как тогда привязать к тексту звук (голосовую запись) и поменять картинку (ну типа кто шлет его?) Пытаюсь создать глобальный мод с новым сюжетом,буду рад любой оказанной помощи Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Привяать звук+иконку сменить --[[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]] news_manager.send_tip(db.actor, "Твой текст", nil, "pda_icon") snd_obj = sound_object([[actor\gazmask_idle]]) snd_obj:play(db.actor,0,sound_object.s2d) pda_icon список иконок посмотри в news_manager.script, можно добавить свои по аналогии Ссылка на комментарий
Daniar299 0 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Вампир35, спс, помогло сделал! Добавлено через 6 мин.: Вот только в энциклопедию закинуть не смог, не робит, ты мог бы написать так же как с группировкой? А что я не понимаю! Ссылка на комментарий
Kondr48 314 Опубликовано 19 Июля 2012 Поделиться Опубликовано 19 Июля 2012 Daniar299, как ты выдаешь инфопоршень? Что не работает, вылет или что? Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти